【问题标题】:How to explain the same structure expression `(?=\w{6,10})\d+ and (?=abc)ad`? [duplicate]如何解释相同的结构表达式`(?=\w{6,10})\d+ and (?=abc)ad`? [复制]
【发布时间】:2026-01-16 14:10:02
【问题描述】:
debian@wifi:~$ echo "348dfgeccvdf" | grep -oP "\d+(?=\w{6,10})"
348
debian@wifi:~$ echo "348dfgeccvdf" | grep -oP "(?=\w{6,10})\d+"
348

对于\d+(?=\w{6,10}),它是标准的正向前瞻表达式。
正如 Wiktor Stribiżew 在帖子中所说的那样
position and negative lookbehind
否定的lookbehind 语法以(?<! and ends with the unescaped ) 开头。无论它出现在模式的开头、中间还是结尾,它都不会停止作为一种消极的后视。
也许位置和整个前瞻(后视)表达式之间没有关系。

根据相同的逻辑推断积极的前瞻,例如 Wiktor Stribiżew 说消极的后瞻:

"\d+(?=\w{6,10})" == "(?=\w{6,10})\d+"

他们都积极向前看。

下面是另一个例子:

echo  "adabc  adabb" |grep -oP  "ad(?=abc)"
ad
echo  "adabc  adabb" |grep -oP  "(?=abc)ad"

为什么"ad(?=abc)"不等于"(?=abc)ad"
如何解释相同的结构表达式(?=\w{6,10})\d+ and (?=abc)ad

【问题讨论】:

  • 环视是zero-length assertions,它们在字符/开始/结束之间的某个位置“触发”。在这个位置,他们“向前或向后看”定义的条件。
  • 在 Wiktors 示例中,他正在更改单词边界 (\b) 的位置和负向后视 - 这是可能的,因为两者都是零宽度断言。在您的示例中,您交换了前瞻模式和匹配模式 - 这导致了根本不同的整体模式。
  • 而你似乎误读了他的无论是出现在模式的开头、中间还是结尾。这并不是说匹配进度与环视位置无关 - 只是环视模式仍然是环视。

标签: regex lookahead negative-lookbehind


【解决方案1】:

Wiktor Stribiżew 说负面回顾:

"\d+(?=\w{6,10})" == "(?=\w{6,10})\d+"

他不是这么说的。他的示例特别使用了单词边界,这也是一个零长度断言。只有

…(?lookaround)\b… == …\b(?lookaround)…

可以持有。

为什么"ad(?=abc)" 不等于"(?=abc)ad"

因为一个在匹配 ad 之后断言序列 abc 而另一个试图在开始时断言它(这将始终失败)。

【讨论】:

    【解决方案2】:

    为什么“ad(?=abc)”不等于“(?=abc)ad”?

    ad(?=abc) 解释 ad 后跟 abc(?=abc)ad 不会与任何输入字符串匹配。导致期待'跟随 abc'(?=abc) 但在积极的前瞻之后定义 ad ! .模式应该是这样的(?=abc)\w+ 来匹配这个输入字符串abcad

    如何解释相同的结构表达式 (?=\w{6,10})\d+ 和 (?=abc)ad ?

    (?=\w{6,10})\d+ 这个模式也不会像这个(?=abc)ad 一样匹配任何输入字符串。模式应该是这样的:

    (?=\w{6,10})\w+(?=abc)\w+

    【讨论】:

      最近更新 更多