正则表达式 - 混淆外观功能

时间:2013-08-14 16:53:33

标签: regex regex-lookarounds

如果我写

(?<=\()\w+(?=\))

用于此字符串:(测试)(测试2)(测试3)

我将得到:Test Test2 Test3

这是有道理的。

如果我写

\w+ (?<=\()\w+(?=\))

对于此字符串:LTE(测试)

它什么也没有返回..这里有什么问题?

请清楚解释你的正则表达,因为它很难阅读。

2 个答案:

答案 0 :(得分:5)

Lookarounds不消耗字符!

这里有一步一步看到它(可能不是最好的,但无论如何我是如何解释的):

第一个字符是L,正则表达式引擎将其与\w+进行比较并同意它匹配。同样适用于T,然后是E

在空间中,正则表达式引擎在正则表达式中看到一个空格,这也很好。

接下来是开场白,但正则表达式看到了什么?请注意,外观不会消耗字符,因此\(中的(?<=\()实际上并未消耗,\(\w+匹配的内容不匹配!

你可能会想到正则表达式实际上消耗了这些字符:\w+ \w+,但是在第二个\w+上有一个条件,它必须在parens之间找到。条件可能会得到满足,但表达式本身与任何括号都不匹配!

要使其匹配,您应该添加parens:

\w+ \((?<=\()\w+(?=\))\)

在查看并匹配空格后,正则表达式引擎看到(,它与提供的表达式一致,它向前移动。

然后引擎会看到T。首先,它是否与下一个字符\w+匹配?是的,第二,之前是否有一个开放式的paren?是。

在前进之前,它看到了一个积极的前瞻。前面还有一个关闭的人吗?不,有e,但\w+仍然可以满足,因此它会将e与另一个\w相匹配。直到t,这种情况仍然如此。在t之后是否有结束语?是的,从而进行下一次检查。

它会遇到一个关闭的paren,它与表达式中的结束paren相匹配(请注意,可以在此处删除文字结束符号,并且您将匹配LTE (Test)。

但是,有了这一切,放弃外观可能同样出色:

\w+ \(\w+\)

因为它们会对发动机造成更大的压力,即使它在小规模上不明显,但在较大的弦上可能会很重要。

希望它有所帮助,即使它有一点点!

答案 1 :(得分:2)

Lookahead和lookbehind是"zero-width assertions",它们不消耗字符串中的字符,但只断言匹配是否可行。您的第二个模式尝试查找<word1><space><word2>结构,但期望<word2>被括号括起来。它不会匹配任何内容,因为它在<word2>之前接受的唯一字符是<space>!我只是将括号直接写入模式:(\w+) \((\w+)\)。我试过了,它给了我LTETest