【问题标题】:Understanding positive and negative lookaheads了解正面和负面的前瞻性
【发布时间】:2014-12-29 15:03:45
【问题描述】:

我试图了解负前瞻对简单示例的作用。例如,考虑以下正则表达式:

a(?!b)c

我认为负前瞻匹配一个位置。因此,在这种情况下,正则表达式匹配任何严格包含 3 个字符且不是 abc 的字符串。

但事实并非如此,如 this demo 所示。为什么?

【问题讨论】:

  • 也许这会有所帮助:regular-expressions.info/lookaround.html
  • @RocketHazmat 是的,它很有帮助,但它是谷歌的第一个结果:) 我读过它
  • 为了增加这个问题,一个常见的误解是你可以使用否定前瞻来代替多词否定,甚至尝试其他方式,所以你会看到像这样的损坏的正则表达式:[A-Za-z]+(?![A-Za-z]),@ 987654326@, (?!sword)fish

标签: regex regex-lookarounds


【解决方案1】:

前瞻不消耗任何字符。它只是检查前瞻是否可以匹配:

a(?!b)c

所以在匹配a 之后,它只是检查,如果它后面不是b 但不消耗not 字符(即c)并且后面是@ 987654328@.

a(?!b)c 如何匹配 ac

ac
|
a

ac
 |
(?!b) #checks but does not consume. Pointer remains at c

ac
 |
 c

正向预测

肯定前瞻的相似之处在于它尝试匹配前瞻中的模式。如果可以匹配,则正则表达式引擎继续匹配模式的其余部分。如果不能,则丢弃匹配项。

例如

abc(?=123)\d+匹配abc123

abc123
|
a

abc123
 |
 b

abc123
  c

abc123 #Tries to match 123; since is successful, the pointer remains at c
    |
 (?=123)

abc123 # Match is success. Further matching of patterns (if any) would proceed from this position
  |

abc123
   |
  \d

abc123
    |
   \d

abc123 #Reaches the end of input. The pattern is matched completely. Returns a successfull match by the regex engine
     |
    \d

【讨论】:

  • 需要注意的是,例如,.+(?!b).+ 如果(?!b) 失败,第一个.+ 将尝试匹配较短的字符串,然后再次进行检查。因此,.+(?!b).+ 将匹配bbbabb,第一个.+ 匹配bbb,第二个匹配abb。 (demo)
  • 与其说发生了回溯,不如说指针从不移动可能更正确。当模式失败时,正则匹配会发生回溯。
  • 您不能记录一下正向前瞻吗?除非它检查(?=pattern) 中的模式是否匹配,否则这是否与否定前瞻相同。
  • @St.Antario 是的。它只是检查模式是否可以匹配。如果可以匹配,它将继续使用其余模式,否则将丢弃。看看this answer which i just answered on look ahead
  • @St.Antario 我还添加了对正向展望的编辑。希望对你有帮助:)
【解决方案2】:

@Antario,我有一段时间对正则表达式中的负面展望/后面情况感到困惑,this 网站有一个很好的解释。

因此,对于您的示例,您要说的是您有一个文字“a”,并且后面没有文字“b”,而是后面跟着文字“c”。

这是一个与您使用的不同的正则表达式调试器,它给出了一个更直观的答案,我个人认为这很有帮助:)

a(?!b)c

Debuggex Demo

【讨论】:

    【解决方案3】:

    a(?!b)c 将仅匹配 ac,因为您将拥有 a 后跟“not b”(不会被消耗)然后是 c 的唯一方法是 ac

    【讨论】:

      【解决方案4】:

      因此,在这种情况下,正则表达式匹配任何严格包含 3 个字符且不是 abc 的字符串

      这不太对。这个正则表达式表明我们正在搜索一个序列,它的第一个符号是a,然后是c,里面没有b

      例如,a(?!b). 将匹配 acaf,因为通过 . 对最后一个符号没有限制

      【讨论】:

      • 不存在字符串以a 开头或以c 结尾的条件。只是它包含ac
      猜你喜欢
      • 2016-09-07
      • 2012-12-13
      • 2013-08-20
      • 2021-10-11
      • 2015-04-23
      • 1970-01-01
      • 2016-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多