Mai*_*tor 1 regex string parsing
这个正则表达式
/\(.*\)/
Run Code Online (Sandbox Code Playgroud)
将不匹配匹配的括号,但匹配字符串中的最后一个括号.是否有正则表达式扩展或类似的东西,具有适当的语法允许这个?例如:
there are (many (things (on) the)) box (except (carrots (and apples)))
Run Code Online (Sandbox Code Playgroud)
/OPEN(.*CLOSE)/ 应该匹配 (many (things (on) the))
可能有无限级别的括号.
如果你只有一个级别的括号,那么有两种可能性.
选项1:使用不合理的重复:
/\(.*?\)/
Run Code Online (Sandbox Code Playgroud)
这将在遇到第一个时停止).
选项2:使用否定字符类
/\([^)]*\)/
Run Code Online (Sandbox Code Playgroud)
这只能重复不重复的字符),因此它必然不会超过第一个右括号.由于性能原因,通常首选此选项.此外,此选项更容易扩展以允许转义括号(以便您可以匹配此完整字符串:(some\)thing)而不是丢弃thing)).但这可能很少需要.
但是,如果你想要嵌套结构,这对于正则表达式来说通常过于复杂(尽管像PCRE这样的一些版本支持递归模式).在这种情况下,您应该自己查看字符串并计算括号,以跟踪当前的嵌套级别.
正如关于这些递归模式的旁注:在PCRE中(?R)只是代表整个模式,因此将其插入某处会使整个事物递归.但是,括号中的每个内容必须与整个匹配的结构相同.此外,实际上不可能对此进行有意义的一步替换,以及在多个嵌套级别上使用捕获组.总而言之 - 你最好不要使用正则表达式来嵌套结构.
更新:由于您似乎渴望找到正则表达式解决方案,以下是使用PCRE匹配示例的方法(PHP中的示例实现):
$str = 'there are (many (things (on) the)) box (except (carrots (and apples)))';
preg_match_all('/\([^()]*(?:(?R)[^()]*)*\)/', $str, $matches);
print_r($matches);
Run Code Online (Sandbox Code Playgroud)
结果是
Array
(
[0] => Array
(
[0] => (many (things (on) the))
[1] => (except (carrots (and apples)))
)
)
Run Code Online (Sandbox Code Playgroud)
模式的作用:
\( # opening bracket
[^()]* # arbitrarily many non-bracket characters
(?: # start a non-capturing group for later repetition
(?R) # recursion! (match any nested brackets)
[^()]* # arbitrarily many non-bracket characters
)* # close the group and repeat it arbitrarily many times
\) # closing bracket
Run Code Online (Sandbox Code Playgroud)
这允许无限的嵌套级别以及无限的并行级别.
请注意,不可能将所有嵌套级别作为单独的捕获组.你将始终只是获得最内层或最外层的组.此外,不能像这样进行递归替换.