使用负向预测先行断言中的 \K 分组

3

我可以否定使用先前的\K组吗? 我可以匹配faxbarfunbarbobarbar,并省略foobarfobarfoooooobar中的bar吗? https://regex101.com/r/qR9kD4/5

正则表达式

fo*\Kbar

字符串:(- 和期望结果)

foobar       - no match
fobar        - no match
foooooobar   - no match
faxbar       - match 'bar'
funbar       - match 'bar'
bobar        - match 'bar'
bar          - match 'bar'
dontmineidontwanttfooooobematchedaatall  - no match

基本上是对我的当前匹配进行反转(除了dontmineme...)。希望我只需要添加一个!或类似的东西!

使用正向先行断言 (?=) - nhahtdh
nhahtdh 不是 Half Life 1 中的最终 Boss 吗?无论如何,我怎样才能在没有任何模式的情况下使用前瞻来“抓住”它呢? - JayTarka
既然问题已经澄清,我的评论就不起作用了。如果您可以过滤匹配项,那么应该是可能的,但不确定是否有无需过滤的方法。 - nhahtdh
3个回答

2
你可以在负预测断言中使用\K:

例如:

\b(?!fo+)\w*\Kbar

演示

一种简单的解决方案是将要忽略的内容放在交替符号的左侧,将要匹配的内容放在捕获组中,位于交替符号的右侧。

fo+bar|\w*(bar)

第一个正则表达式如何使用?例如,'fobar' =~ /fo*bar|\w*\K(bar)/] #=> 0。(与/fo+bar.../相同。) - Cary Swoveland
你的第二个正则表达式通过了我的答案测试。你的第一个正则表达式在前三个测试中失败了,但在其他测试中通过了。我将最后一行改为 ].each { |str,result| puts (!!(str =~ R) == result) } 并将 R 设置为你的正则表达式。 - Cary Swoveland
@hwnd 这比任何东西都更易懂...但是为什么我的负向先行断言忽略了空格 https://regex101.com/r/dP9fM7/3?第二行不应该匹配吗? - JayTarka

2
如果您可以使用锚点,那么这可能是可行的。 它们使您能够确保在前瞻中查看的 bar 与主正则表达式中消耗的相同的 bar
^(?!fo+bar$)[a-z]*\Kbar$

\b(?!fo+bar\b)[a-z]*\Kbar\b

如果您无法使用锚点,可能是不可能的。我们需要了解更多关于您预期看到的字符串的信息,以及更详细的匹配标准。
但我必须问一下,您真的必须使用\K吗?回溯可能似乎是显而易见的方法,但通常更容易使用捕获组。
\b(?!fo+bar\b)[a-z]*(bar)\b

你只需使用$~[1]而非$&来提取你感兴趣的子字符串。

我的答案中所有的测试都通过了。 - Cary Swoveland

1
这应该可以做到:

R = /^fo|bar/
str[R]=='bar'

尽管它没有使用\K
[
  ['foobar',                                  false],
  ['fobar',                                   false],
  ['foooooobar',                              false],
  ['faxbar',                                  true ],
  ['funbar',                                  true ],
  ['bobar',                                   true ],
  ['bar',                                     true ],
  ['dontmineidontwanttfooooobematchedaatall', false],
].each { |str,result| (str[R]=='bar') == result }
true
true
...
true

其他提供答案的人可能想使用我的测试代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接