我有一个正则表达式,其中包含一个强制部分、一个非贪婪(懒惰?)部分、一个可选部分,最后是另一个非贪婪部分。
<mandatory><non-greedy><optional><non-greedy>
实现为:
^mandatory.*?(:?optionalpart)?.*?$
可选部分由'要查找的一 block '和'要在捕获组中返回的一 block '组成。
^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 , 但我们都没有满意的答案。
最佳答案
您的第一个正则表达式非常接近,您需要将 (?:
向左移动一点以包含 .*?
模式:
^Foo:(?: .*?2,([a-z]))?.*$
^^^
参见 regex demo
详情
^
- 字符串的开始Foo:
- 一些文字(?: .*?2,([a-z]))?
- 匹配贪婪的可选非捕获组(将至少尝试一次)出现 1 次或 0 次:.*?
- 空格后跟除换行符以外的任何 0+ 个字符,尽可能少2,
- 文字子串([a-z])
- 第 1 组:小写字母
.*
- 除换行符以外的任何 0+ 个字符(字符串的其余部分)$
- 字符串结尾。
一般的模式是这样的
^<MANADATORY_LITERAL>(?:<NON_GREEDY_DOT>(<OPTIONAL_PART>))?<GREEDY_DOT>$
关于java - 防止非贪心部分消费后面的可选部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53303431/