我在以下正则表达式中找到了它:
\[(?:[^][]|(?R))*\]
它将方括号(及其内容)与嵌套的方括号相匹配。
答案 0 :(得分:65)
[^][]
是一个字符类,表示除[
和]
之外的所有字符。
您可以避免转义[
和]
个特殊字符,因为它对于preg_
函数中使用的正则表达式引擎PCRE并不明确。
由于PCRE中的[^]
不正确,因此正则表达式解析的唯一方法是]
在字符类中,稍后将关闭。与随后的[
相同。它无法在字符类中重新打开字符类(POSIX字符类[:alnum:]
除外)。然后最后]
是明确的;它是角色类的结尾。但是,必须转义字符类外部的[
,因为它被解析为字符类的开头。
以同样的方式,您可以在不转义字符类中的[]]
或[[]
的情况下编写[^[]
或[
或]
。
你可以将这种语法与几种正则表达式一起使用:PCRE(PHP,R),Perl,Python,Java,.NET,GO,awk,Tcl(如果用大括号划分你的模式,感谢Donal Fellows ),...
但不是:Ruby,JavaScript(除了IE< 9 ),......
正如m.buettner所说,[^]]
并不含糊,因为]
是第一个字符,[^a]]
被视为所有不是a
后跟]
。要拥有a
和]
,您必须写:[^a\]]
或[^]a]
在JavaScript的特定情况下,规范允许[]
作为从不匹配的正则表达式标记(换句话说,[]
将始终失败)和{{1} }作为匹配任何字符的正则表达式。然后,[^]
被视为任何字符,后跟[^]]
。实际的实现方式各不相同,但现代浏览器通常都遵循规范中的定义。
模式详细信息:
]
在您的模式示例中,您无需转义最后一个\[ # 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
可避免交替费用。