我有一个正则表达式,其中有一个强制性部分,一个非贪婪(懒惰?)部分,一个可选部分以及最后一个非贪婪部分。
<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,但我们两个人都没有令人满意的答案。
答案 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>$