【问题标题】:Lookahead confusion前瞻混乱
【发布时间】:2010-08-16 18:11:49
【问题描述】:

好的,我从正则表达式食谱中得到了这个例子

^(?=.{3}$).*

上面的正则表达式用于限制任意模式的长度

如果我再次测试'aaabbb',它会完全失败

据我了解,它会查找长度为任何字符 3 的任何字符。所以它应该匹配 'bbb' 但它不是

还有一个问题,应该遵循这个模式 x(?=x)

【问题讨论】:

  • 您使用的是前瞻断言,因为它查看尚未使用的字符。后视断言将查看已使用的字符。
  • 但是你到底想完成什么?
  • 已编辑:限制任意模式的长度
  • @slier: 但^(?=.{3}$) 只会匹配长度为 3 的字符串。所以aaabbb(长度为六)不会匹配。
  • 前瞻断言是非消耗性的(如 Gumbo 所述),它只是检查即将出现的字符以查看它们是否满足约束。在这种情况下,您的模式首先查看字符串的开头,然后执行前瞻断言。这将检查三个字符,它们分别与 3 个 a 匹配,然后检查字符串的结尾。由于字符串的结尾不是直接在前三个字符之后,因此前瞻失败,因此模式失败。

标签: regex regex-lookarounds


【解决方案1】:

这实际上是一个前瞻断言而不是一个后瞻断言。 ^ 将匹配锚定在字符串的开头,然后它断言字符串的开头必须跟 3 个字符,然后是字符串的结尾。

编辑:我可能应该提到最后的 .* 用于匹配这三个字符,因为前瞻断言不消耗任何字符。

【讨论】:

  • 不消耗任何字符是什么意思?
  • 我的意思是,在完成前瞻断言之后,正则表达式引擎会继续从它进入前瞻的那一点开始比较字符串。因此,给定模式^(?=foo)(.*)$ 和输入foobar,捕获组1 捕获的值将是foobar。该模式将首先执行前瞻,即检查字符串的开头是否为 foo,然后它将移动到 .*,因为前瞻不消耗任何字符,这意味着 .* 匹配的第一个字母是f 然后 o 以此类推,直到它捕获 'foobar'
【解决方案2】:

据我了解,它会查找长度为任何字符 3 的任何字符。所以它应该匹配 'bbb' 但它不是

不!让我们仔细看看...

^        # The caret is an anchor which denotes "STARTS WITH"
(?=      # lookahead
   .     # wildcard match; the . matches any non-new-line character
    {3}  # quantifier; exactly 3 times
   $     # dollar sign; I'm not sure if it will act as an anchor but if it did it would mean "THE END"
)        # end of lookbehind
.        # wildcard match; the . matches any non-new-line character
 *       # quantifier; any number of times, including 0 times

几个问题:

  1. 插入符号要求.* 是字符串中的第一个字符,然后您尝试在它们后面查找介于开头^ 和第一个字符.* 之间的字符。
  2. 您的.{3}实际上是指任意三个字符,而不是任何重复三次的字符;)您实际上想知道How can I find repeated letters with a Perl regex?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-22
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-06
    相关资源
    最近更新 更多