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

标签 java regex non-greedy

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

<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/

相关文章:

java - 客户端-服务器编程中出现错误

Java fasterxml.jackson 反序列化 LocalDateTime wrongTokenException

javascript - 正则表达式 - 至少 1 个数字、1 个字母、1 个特殊字符和至少 3 个字符

regex - 如何编写非贪婪匹配的正则表达式?

PHP preg_replace 将 **xyz** 转换为 <b>xyz</b>

java - 排除maven中的嵌套传递依赖

java - 在一行上打印随机数组 : Java

正则表达式 - 搜索不包含整个单词的文本

python - 将文本拆分到关联表时无法显示文本列

Python 正则表达式速度 - 贪婪与非贪婪