PCRE中的负向前瞻、负向后顾和多个字符。

3

我有以下文本:

aabbaa
aa bbc aa

bbg

aa           bbd   aa

我希望能够使用PCRE查找以“bb”开头的单词,这些单词不在“aa”和“aa”之间,并且无论匹配单词前面或后面是否有空格。在上面的例子中,只有“bbg”应该被匹配。
我已经创建了以下模式:
(?<!aa)bb(\w)*(?!aa)

然而只有aabbaa没有匹配成功,其他都匹配了。我不知道如何在否定的前/后瞻中使用\s*来得到所需的结果。似乎不能简单地使用:

(?<!aa\s*)bb(\w)*(?!\s*aa)

如何实现呢?

须先将正向预查设为零长度后,再在其外指定量词。 - Unihedron
1
@Unihedron 是的,我知道这个,但我不知道如何实现这个结果。 - Marcin Nabiałek
1个回答

3

(*SKIP)(*F) 魔法(无需前瞻)

使用这个:

(\baa\b).*?\1(*SKIP)(*F)|\bbb\w+\b

请看演示匹配结果。 这个问题是一个典型的技术问题,在这个问题中讲解了一种正则表达式匹配模式的技巧,可以排除一部分匹配结果。在这个正则表达式中,左边的|匹配完整的aa ... aa字符串,然后有意失败,引擎跳过该字符串继续匹配下一个位置。右侧匹配您需要的bb...单词,并且我们知道他们是正确的,因为它们没有被左侧的表达式匹配到。详情请参考以下内容:

为什么文档中完全没有提到这些功能呢?我几年前就可以用上它们了! - Niet the Dark Absol
目前我不知道它是如何工作的,但我会尽快理解它。谢谢。 - Marcin Nabiałek
Marcin,这篇链接文章详细解释了它。这是一种美丽而简单的技术。 :) - zx81
@NiettheDarkAbsol 这里是关于该主题的Perl文档PCRE文档中也有一些内容,但不如Perl文档详细。 :) - zx81
1
Marcin,理解的关键在于|有两个方面...左边用于跳过不想要的内容,即aa..aa之类的东西...然后在右边,你可以自由匹配bbetc,因为任何不良上下文已经被中和了。这很简单而且很强大。 :) - zx81

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