REGEX: Select KeyWord1 如果 KeyWord2 在同一个字符串中

REGEX: Select KeyWord1 if KeyWord2 is in the same string

我正在尝试根据字符串中是否存在 KeyWord2 在 .NET 正则表达式引擎 中捕获 KEYWORD1。到目前为止,我正在使用的正向环视解决方案:

(?=.*KeyWord2)**KEYWORD1** (\m\i)

RegEx Test Link

如果 KeyWord2 位于字符串中 KEYWORD1 后面的任何位置,

仅捕获 KEYWORD1。我如何在正则表达式中优化它,以便它捕获字符串中 KEYWORD1 的所有实例,尽管 KeyWord2 的位置在前面,后面或两者?

非常感谢您提供一些见解。

谢谢

您可以使用下面的正则表达式来满足您的要求:

\bKEYWORD1\b(?:(?<=\bKeyWord2\b.*?)|(?=.*?\bKeyWord2\b))

上面正则表达式的解释:

gi - Use the flags(in order to avoid any case difference) representing: g - global; i - case-insensitive

\b - Represents a word boundary.

(?:) - Represents a non-capturing group.

(?=.*?KeyWord2) - Represents the positive lookahead which matches all KEYWORD1 which are before KeyWord2 read from left to right.

| - Represents alternation; that is it alternates between 1st and 2nd alternating group.(Although, you can wrap them in group.)

(?<=KeyWord2.*?) - Represents infinite(because non-fixed width lazy identifier .*? used) positive lookbehind which matches all KEYWORD1 which are behind of KeyWord2.

你可以找到上面的正则表达式演示here.

注意 - 根据记录,这些引擎支持无限后视:

据我所知,只有他们。

如果使用支持 \G\K 的正则表达式引擎,则可以使用以下正则表达式。

^(?=.*\bKeyWord2\b)|\G.*?\K\bKEYWORD1\b

设置不区分大小写的标志,并根据要求设置多行标志。

PCRE demo

使用 PCRE (PHP) 和其他一些正则表达式引擎,锚点 \G 匹配上一场比赛的结尾。对于第一次匹配尝试,\G 等同于 \A,匹配字符串的开头。有关详细信息,请参阅 this discussion

\K 将报告匹配的起点重置为引擎内部字符串指针的当前位置。任何先前消耗的字符都不包含在最终匹配中。实际上,\K 使引擎 "forget" 匹配到该点的所有内容。详情可见here.

如link处所示,有4个匹配的字符串

The KEYWORD1 before KeyWord2 then KEYWORD1 and KEYWORD1 again

它们是字符串开头的空字符串和KEYWORD1的三个实例中的每一个。事实上,对于每个匹配的字符串,其中一个匹配项将是字符串开头的空字符串。因此,在进行替换时必须忽略空字符串。