【问题标题】:Regexp lazy quantifier正则表达式惰性量词
【发布时间】:2015-12-07 10:06:48
【问题描述】:

我有这样一句话

a something* q b c w

而且我必须像

一样将 aq 匹配在一起
(id_1: a, id_2: q)

b单独喜欢

(id_1: b)

cw在一起就好 (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)

正如预期的那样。

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

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

最后一个正则表达式是:

(?:\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”(由于 .* 上的惰性运算符)。

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

【问题讨论】:

标签: regex


【解决方案1】:

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

如果您需要匹配一些不是特定文本的文本,您可以使用 2 个东西:经过调和的贪婪令牌或基于 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

【讨论】:

  • 如果您有多行输入,请不要忘记使用re.DOTALL/re.S 标志,以便. 可以匹配换行符。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多