防止非贪心部分消费后面的可选部分

Prevent non-greedy part from consuming the following optional part

我有一个正则表达式,其中包含强制部分、非贪婪(惰性?)部分、可选部分和最后的非贪婪部分。

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

可选部分由'a piece to find'和'a piece to return in a capture group'组成。

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

但对于某些输入,第一个非贪婪部分会消耗后续可选部分应匹配的字符。有没有办法让可选部分比之前的非贪心部分更贪心?


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

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

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

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

如果重要的话,我正在使用 Java 的模式 class。

--

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

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

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

regex demo

详情

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

一般的模式看起来像

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