【问题标题】:regex - confused about lookaround functionality正则表达式 - 对环视功能感到困惑
【发布时间】:2013-08-14 16:53:32
【问题描述】:

如果我写

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

对于这个字符串:(Test) (Test2) (Test3)

我会得到:Test Test2 Test3

这是有道理的。

如果我写

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

对于这个字符串:LTE(测试)

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

请清楚地解释您的正则表达式,因为它可能难以阅读。

【问题讨论】:

  • 使用gskinner.com/RegExr :将鼠标悬停在您的正则表达式代码上以查看清晰的解释。另请参阅regex101.com/r/zE8qZ8
  • 我首先使用 regexr 来测试它。仍然没有让我清楚为什么它不起作用

标签: regex regex-lookarounds


【解决方案1】:

环视不消耗字符!

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

第一个字符是L,正则表达式引擎将它与\w+ 进行比较,并同意它是匹配的。 TE 也是如此。

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

接下来是开头的括号,但是正则表达式看到了什么?请记住,环视不消耗字符,因此(?&lt;=\() 中的\( 实际上并没有被消耗,\(\w+ 匹配的内容不匹配!

您可能会想到实际使用这些字符的正则表达式:\w+ \w+,但在第二个\w+ 上有一个条件,即必须在括号之间找到它。条件可能满足,但表达式本身不匹配任何括号!

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

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

在看到并匹配空格后,正则表达式引擎看到(,与提供的表达式一致,它继续前进。

然后引擎会看到T。首先,它是否匹配下一个字符\w+?是的,第二,在它之前有一个开头的括号吗?是的。

在前进之前,它看到了积极的展望。前面有一个关闭的paren吗?不,有e,但\w+ 仍然可以满足,所以它匹配e 与另一个\w。这种情况一直持续到tt 之后是否有结束括号?是的,因此继续下一步检查。

它遇到了一个右括号,它与表达式中的右括号相匹配(请注意,可以在此处删除文字的右括号,而您将匹配LTE (Test)。

但有了这一切,放弃环视可能同样好:

\w+ \(\w+\)

因为它们给引擎增加了更多的压力,即使它在小范围内不那么明显,但在更大的字符串上可能很重要。

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

【讨论】:

  • 所以基本上.. 环视真的不能用在正则表达式的中心吗?在我的第一个示例中,我得到了所有没有括号的“测试”,但我不会得到 LTE。如果我想要 LTE,那么我应该明确说明有括号吗?我不完全明白。
  • @hamobi 您可以在正则表达式的中心使用它,但这是否有用将是个问题。通常,尽量避免使用它们,仅在必要时使用它们。它们通常需要更多的处理时间。
【解决方案2】:

Lookahead 和lookbehind 是"zero-width assertions",它们不消耗字符串中的字符,而只是断言匹配是否可能。您的第二个模式试图找到一个&lt;word1&gt;&lt;space&gt;&lt;word2&gt; 结构,但它希望&lt;word2&gt; 被括号包围。它不会匹配任何东西,因为它在&lt;word2&gt; 之前接受的唯一字符是&lt;space&gt;!我只需将括号直接写入模式:(\w+) \((\w+)\)。我试过了,它给了我LTETest

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    相关资源
    最近更新 更多