我在以下正则表达式中找到了它:
\[(?:[^][]|(?R))*\]
它将方括号(及其内容)与嵌套的方括号匹配。
[^][]是一个字符类,表示除[and之外的所有字符]。
您可以避免转义[和]特殊字符,因为它对于 PCRE(preg_函数中使用的正则表达式引擎)没有歧义。
由于[^]在 PCRE 中不正确,因此正则表达式解析的唯一方法]是在稍后将关闭的字符类中。下同[。它不能在字符类中重新打开字符类(POSIX 字符类除外[:alnum:])。然后最后一个]很清楚;这是字符类的结束。但是,[必须对字符类外部的字符进行转义,因为它被解析为字符类的开头。
同样,您可以在字符类中编写[]]or[[]或[^[]不转义[or 。]
注意:从 PHP 7.3 开始,您可以使用 inline xx 修饰符,即使在字符类中也可以忽略空白字符。这样你就可以用一种不那么模棱两可的方式来编写这些类:(?xx) [^ ][ ] [ ] ] [ [ ] [^ [ ].
您可以将此语法与几种正则表达式一起使用:PCRE (PHP, R), Perl, Python, Java, .NET, GO, awk, Tcl
但不适用于:Ruby、JavaScript(IE < 9 除外)、...
正如 m.buettner 所指出的,[^]]它并不模棱两可,因为]它是第一个字符,[^a]]被视为所有不是 aa后跟 a]的字符。要拥有aand ],您必须编写:[^a\]]或[^]a]
在 JavaScript 的特定情况下,规范允许[]作为一个从不匹配的正则表达式标记(换句话说,[]总是失败)和[^]一个匹配任何字符的正则表达式。然后[^]]被视为后跟一个的任何字符]。实际实现各不相同,但现代浏览器通常坚持规范中的定义。
图案细节:
\[ # literal [
(?: # open a non capturing group
[^][] # a character that is not a ] or a [
| # OR
(?R) # the whole pattern (here is the recursion)
)* # repeat zero or more time
\] # a literal ]
在您的模式示例中,您不需要转义最后一个]
但是你可以对这个模式做同样的事情,稍微优化一下,更有用的原因是可以作为子模式重用(使用(?-1)):(\[(?:[^][]+|(?-1))*+])
( # open the capturing group
\[ # a literal [
(?: # open a non-capturing group
[^][]+ # all characters but ] or [ one or more time
| # OR
(?-1) # the last opened capturing group (recursion)
# (the capture group where you are)
)*+ # repeat the group zero or more time (possessive)
] # literal ] (no need to escape)
) # close the capturing group
或更好:(\[[^][]*(?:(?-1)[^][]*)*+])这避免了交替的成本。