如果我写
(?<=\()\w+(?=\))
用于此字符串:(测试)(测试2)(测试3)
我将得到:Test Test2 Test3
这是有道理的。
如果我写
\w+ (?<=\()\w+(?=\))
对于此字符串:LTE(测试)
它什么也没有返回..这里有什么问题?
请清楚解释你的正则表达,因为它很难阅读。
答案 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+)\)
。我试过了,它给了我LTE
和Test
。