[英]How do I match nested braces using regular expressions in PHP?
我有一个我想要匹配的LaTeX文档。 我需要一个符合以下条件的RegEx匹配:
\ # the backslash in the beginning
[a-zA-Z]+ #a word
(\{.+\})* # any amount of {something}
然而,她是抓住了;
在最后一行中,它需要贪婪,并且2.需要在其内部具有匹配的数量{}
。
这意味着如果我有字符串\\test{something\\somthing{9}}
它将匹配整个。 它需要按顺序( {}
)。 因此它与以下内容不匹配:
\\ LaTeX {}是\\ TeX {}的文档准备系统
只是
\\胶乳{}
和
\\ TeX的{}
帮助任何人? 也许有人有更好的匹配想法? 我不应该使用正则表达式吗?
这可以通过递归来完成:
$input = "\LaTeX{} is a document preparation system for the \TeX{}
\latex{something\somthing{9}}";
preg_match_all('~(?<token>
\\\\ # the slash in the beginning
[a-zA-Z]+ #a word
(\{[^{}]*((?P>token)[^{}]*)?\}) # {something}
)~x', $input, $matches);
这正确匹配\\LaTeX{}
, \\TeX{}
和\\latex{something\\somthing{9}}
可以使用PHP ,因为它支持递归正则表达式匹配。 但是 ,正如我所说的,如果你的类似LaTeX的字符串中有注释可以包含{
或}
,那么这将失败。
演示:
$text = 'This is a \LaTeX{ foo { bar { ... } baz test {} done } } document
preparation system for the \TeX{a{b{c}d}e{f}g{h}i}-y people out there';
preg_match_all('/\\\\[A-Za-z]+(\{(?:[^{}]|(?1))*})/', $text, $matches, PREG_SET_ORDER);
print_r($matches);
产生:
Array
(
[0] => Array
(
[0] => \LaTeX{ foo { bar { ... } baz test {} done } }
[1] => { foo { bar { ... } baz test {} done } }
)
[1] => Array
(
[0] => \TeX{a{b{c}d}e{f}g{h}i}
[1] => {a{b{c}d}e{f}g{h}i}
)
)
快速解释:
\\\\ # the literal '\'
[A-Za-z]+ # one or more letters
( # start capture group 1 <-----------------+
\{ # the literal '{' |
(?: # start non-capture group A |
[^{}] # any character other than '{' and '}' |
| # OR |
(?1) # recursively match capture group 1 ---+
) # end non-capture group A
* # non-capture group A zero or more times
} # the literal '}'
) # end capture group 1
不幸的是,我认为这是不可能的。 支架匹配(检测正确配对的嵌套括号)通常用作有限状态机无法解决的问题的示例,例如正则表达式解析器。 您可以使用无上下文语法来完成它,但这不是正则表达式的工作原理。 您最好的解决方案是使用正则表达式{*[^{}]*}*
进行初始检查,然后使用另一个短脚本来检查它是否为偶数。
总之:不要只用正则表达式来做。 这不是单独用正则表达式解决的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.