防止非贪婪的部分消耗以下可选部分

时间:2018-11-14 15:18:31

标签: java regex non-greedy

我有一个正则表达式,其中有一个强制性部分,一个非贪婪(懒惰?)部分,一个可选部分以及最后一个非贪婪部分。

<mandatory><non-greedy><optional><non-greedy>
实施为:
^mandatory.*?(:?optionalpart)?.*?$

可选部分由“要查找的部分”和“要在捕获组中返回的部分”组成。

^mandatory.*?(:?findme(matchme))?.*?$

但是对于某些输入,第一个非贪婪部分会使用以下可选部分应匹配的字符。有没有办法使可选部分比之前的非贪婪部分更贪婪?


示例:找到2,之后的字符,如果没有2,但必填部分匹配,则找到一个空字符串。

"Foo: 2,b,1,a,3,c" -> match, $1 = "b"
"Foo: 1,a,2,b,3,c" -> match, $1 = "b"
"Foo: 1,a,3,c,2,b" -> match, $1 = "b"
"Foo: 2,b"         -> match, $1 = "b"
"Foo: 1,a,3,c"     -> match, $1 = ""
"Fuu: 1,a,2,b,3,c" -> no match.

尝试1:^Foo: .*?(?:2,([a-z]))?.*?$
在第二个和第三个示例中,此操作失败,返回""而不是"2"

尝试2:^Foo: .*?(?:2,([a-z])).*?$
这修复了先前的失败,但现在在第5个示例上失败,不匹配。
必须是可选的部分不再是可选的。

如果有关系,我正在使用Java的Pattern类。

-

有人问before,但我们两个人都没有令人满意的答案。

1 个答案:

答案 0 :(得分:1)

您的第一个正则表达式非常接近,您需要向左移动(?:才能包含.*?模式:

^Foo:(?: .*?2,([a-z]))?.*$
     ^^^ 

请参见regex demo

详细信息

  • ^-字符串的开头
  • Foo:-一些文字
  • (?: .*?2,([a-z]))?-与 greetily 匹配的可选非捕获组(将至少尝试一次)1次或0次出现:
    • .*?-空格后跟除换行符以外的任何0+字符,并且尽可能少
    • 2,-文字子字符串
    • ([a-z])-第1组:小写字母
  • .*-除换行符(字符串的其余部分)以外的任何0+字符
  • $-字符串的结尾。

一般模式如下

^<MANADATORY_LITERAL>(?:<NON_GREEDY_DOT>(<OPTIONAL_PART>))?<GREEDY_DOT>$