"[^] []"正则表达式是什么意思?

Ema*_*sev 41 php regex

我发现它在以下正则表达式中:

\[(?:[^][]|(?R))*\]
Run Code Online (Sandbox Code Playgroud)

它将方括号(及其内容)与嵌套方括号相匹配.

Cas*_*yte 68

[^][]是一个字符类,表示除[和之外的所有字符].

您可以避免转义[]特殊字符,因为PCRE(preg_函数中使用的正则表达式引擎)不明确.

由于[^]在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\]][^]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 ]
Run Code Online (Sandbox Code Playgroud)

在您的模式示例中,您不需要转义最后一个 ]

但是你可以对这个模式做一点点优化,更有用的原因可以重用为子模式(带有(?-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
Run Code Online (Sandbox Code Playgroud)

或更好:(\[[^][]*(?:(?-1)[^][]*)*+])这可以避免交替的成本.

  • ...但是你应该*逃避那些特殊字符,因为它会让维护代码的人感到困惑.:)正则表达式的作者倾向于喜欢"棘手"的代码(我对此感到内疚),但棘手的代码是难以理解的代码. (29认同)
  • @cdhowie:特别是如果你也在JavaScript中工作,`[^]`是一个有效的正则表达式(意思是"任何字符") (11认同)
  • 请注意,这里重要的一点是`]`作为第一个字符出现(在否定之后),因为不允许使用空类. (3认同)
  • @TimPietzcker除了IEs <9之外,其中`[^]`就像PHP一样在这个答案中 (3认同)
  • @CasimiretHippolyte这不是关于他们是否*能够*解析正则表达式,而是关于你是否已经清楚地表达了你的正则表达式的预期含义.大多数语言都不认为空白是重要的,但我们通过在自己的行上放置语句来大量使用它.这不是为了编译器的利益,而是为了未来维护者的利益.这是另一个这样的情况,编译器可能不在乎,但是下一个维护代码的人会欣赏不必停下来并试图猜测你的意图是什么. (2认同)
  • @CasimiretHippolyte,我将不得不同意cdhowie在这一个...在这种情况下不使用转义字符是可怕的.除非您为自己的个人娱乐编写纯粹的一次性代码,否则某人*必须维护您的代码*.不要因为你认为他们不存在而成为那个人的混蛋. (2认同)