匹配键值模式正则表达式
我正在制作一个键值解析器,其中输入字符串采用的形式key:"value",key2:"value"
。键可以包含字符a-z
,A-Z
并且0-9
和值可以包含任何字符,但:
,,
,"
和\
需要用反斜杠前缀。逗号用于分隔键值对,但在最后一对之后不需要。
到目前为止,我已经([a-zA-Z0-9]+):"(.*)"
可以匹配大多数键和值,但是很显然它将不能处理多于一对的字符或者任何“控制”字符都不能转义。(?<=\\)[:,"\\]
似乎匹配所有转义字符,但不匹配任何“正常”字符。
有没有办法检查逗号分隔并匹配所有转义的“控制”字符以及普通字符?这是不是更适合没有正则表达式的实现的东西吗?还是需要顺序使用多个模式?
一些例子:
输入:joe:"bread",sam:"fish"
输出:joe -> bread
sam -> fish
输入:joe:"Look over there\, it's a shark!",sam:"I like fish."
输出:joe -> Look
over there, it's a shark!sam -> I like fish
回答:
假定\
除行终止符之外的任何字符都指定紧随其后的字符。
您可以使用以下正则表达式来匹配键值对的所有实例:
"([a-zA-Z0-9]+):\"((?:[^\\\\\"]|\\\\.)*+)\""
如果要允许自由间距\\s*
,请在之前和之后添加:
。
这是正则表达式引擎看到的内容:
([a-zA-Z0-9]+):"((?:[^\\"]|\\.)*+)"
量词*
由所有格*+
,由于2个分支[^\\"]
并\\.
是互斥(没有字符串可由两个在同一时间相匹配)。它还避免StackOverflowError
了在Oracle的实现Pattern
类。
在Matcher循环中使用上述正则表达式:
Pattern keyValuePattern = Pattern.compile("([a-zA-Z0-9]+):\"((?:[^\\\\\"]|\\\\.)*+)\"");Matcher matcher = keyValuePattern.matcher(inputString);
while (matcher.find()) {
String key = matcher.group(1);
// Process the escape sequences in the value string
String value = matcher.group(2).replaceAll("\\\\(.)", "$1");
// ...
}
在一般的情况下,根据不同的转义序列的复杂性(例如\n
,\uhhhh
,\xhh
,\0
),你可能会想要写一个单独的函数来分析它们。但是,基于上述假设,单线就足够了。
请注意,尽管如此,该解决方案并不关心分隔符。并且它将在无效输入上跳至最接近的匹配项。在下面的无效输入示例中,以上解决方案将abc:"
在开头跳过并愉快地将xyz:"text
text"amd more:"pair"
作为键值对进行匹配:
abc:"xyz:"text text", more:"pair"
如果这种行为不是所希望的,那么有一个解决方案,但是必须首先隔离包含所有键值对的字符串,而不是使其成为与键值对没有任何关系的更大字符串的一部分:
"(?:^|(?!^)\\G,)([a-zA-Z0-9]+):\"((?:[^\\\\\"]|\\\\.)*+)\""
免费版本:
"(?:^\s*|(?!^)\\G\s*,\s*)([a-zA-Z0-9]+)\s*:\s*\"((?:[^\\\\\"]|\\\\.)*+)\""
以上是 匹配键值模式正则表达式 的全部内容, 来源链接: utcz.com/qa/420417.html