正则表达式惰性量词

标签 regex

我有一个这样的句子

a something* q b c w

我必须将 a 和 q 匹配在一起,例如
(id_1: a, id_2: q)

b 一个人喜欢
(id_1: b)

和 c 和 w 一起喜欢
(id_1:c id_2:w)

我尝试使用这个正则表达式
(?:\b(?P<id_1>a|b|c)\b(?:.*?)(?P<id_2>q|w)?\b)

由于惰性运算符 .*? 正则表达式只匹配句子的第一部分,只匹配
(id_1: a, id_1: b, id_1: c)

Live Example

如果我们使用贪心运算符使得表达式变成
(?:\b(?P<id_1>a|b|c)\b(?:.*)(?P<id_2>q|w)?\b)

Live Example

它匹配
(id_1: a)

之后的所有内容都匹配为 .* .

如果第二部分是强制性的(懒惰在 .* 上):
(?:\b(?P<id_1>a|b|c)\b(?:.*?)(?P<id_2>q|w)\b)

Live Example

它匹配像这样的句子
(id_1: a, id_2: q);(id_1: b, id_2: w)

正如预期的那样。

可以使用“首选”匹配整个句子(包括可选部分)或仅匹配第一部分的正则表达式 如果缺少可选的。

编辑:
抱歉,提供的正则表达式有一些错误。

最后一个正则表达式是:
(?:\b(?P<id_1>a|b|c)\b(?:.*?)(?P<id_2>q|w)\b)

它要求两个组都是强制性的。它匹配“a something* w”,但不匹配“a something*”或仅匹配“a”。我需要匹配“a something* w”以及“a”和“a w”并分别获得匹配组:
(id_1: a , id_2: w) ; (id_1: a, id_2: none) ; (id_1:a , id_2: w)

我认为所需的正则表达式是:
(?:\b(?P<id_1>a|b|c)\b(?:.*?)(?P<id_2>q|w)?\b)

但是在句子“a something* w”中,它只匹配“a”(由于 .* 上的惰性运算符)。

我还更新了所有实时示例。

最佳答案

惰性点匹配是问题的根本原因,因为它需要存在一个尾随边界。

如果你需要匹配一些不是特定文本的文本,你可以使用 2 种东西:一个温和的贪婪 token 或一个 unroll-the-loop基于正则表达式。

如果你有变量,你可以使用 tempered greedy token并使用 ? 将第二个捕获组设为可选量词:

\b(?P<id_1>a|b|c)\b(?:(?!\b(?:a|b|c|q|w)\b).)*(?P<id_2>q|w)?\b
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^             ^

regex demo

关于正则表达式惰性量词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34130933/

相关文章:

javascript - 在 Chrome 中工作,但在 Safari 中中断 : Invalid regular expression: invalid group specifier name/(? <=\/)([^#]+)(?=#*)/

python - 如何抓取另一个 html 行后面的特定 html 行

Python re.sub 将部分字符串更改为 ascii

javascript html 正则表达式

java - 正则表达式仅从 html 中删除某些标签

regex - 否定 RE2 语法中的匹配?

java - 正则表达式,如何识别由空格分隔的 2 或 3 个单词(任何非空格)

javascript - 从 html 字符串中删除 div 及其内容

regex - vim 正则表达式搜索和递增数字

javascript - 用 Javascript 替换双斜杠的正则表达式