我有这样一句话
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)
如果我们使用贪婪的运算符使表达式成为
(?:\b(?P<id_1>a|b|c)\b(?:.*)(?P<id_2>q|w)?\b)
它匹配
(id_1: a)
之后的所有内容都匹配为.*.
如果第二部分是强制性的(懒惰的话.*):
(?:\b(?P<id_1>a|b|c)\b(?:.*?)(?P<id_2>q|w)\b)
它匹配句子
(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)
并且它要求两个组都是强制性的.它匹配“某事物* w”,但它与“某物*”或“a”不匹配.我需要匹配“a * * 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”(由于.*上的懒惰运算符).
我还更新了所有实例.
解决方法
惰性点匹配是一个问题的根本原因,因为它需要存在尾随边界.
如果您需要匹配一些非特定文本的文本,您可以使用两件事:一个是驯化的贪婪令牌或一个基于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 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^