匹配键值模式正则表达式

我正在制作一个键值解析器,其中输入字符串采用的形式key:"value",key2:"value"。键可以包含字符a-zA-Z并且0-9和值可以包含任何字符,但:,"\需要用反斜杠前缀。逗号用于分隔键值对,但在最后一对之后不需要。

到目前为止,我已经([a-zA-Z0-9]+):"(.*)"可以匹配大多数键和值,但是很显然它将不能处理多于一对的字符或者任何“控制”字符都不能转义。(?<=\\)[:,"\\]似乎匹配所有转义字符,但不匹配任何“正常”字符。

有没有办法检查逗号分隔并匹配所有转义的“控制”字符以及普通字符?这是不是更适合没有正则表达式的实现的东西吗?还是需要顺序使用多个模式?

一些例子:

输入:joe:"bread",sam:"fish"输出:joe -> breadsam -> 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

回到顶部