防止非贪心部分消费后面的可选部分
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]))?.*$
^^^
详情
^
- 字符串开头
Foo:
- 一些文字
(?: .*?2,([a-z]))?
- 匹配 greedily 的可选非捕获组(将至少尝试一次)出现 1 次或 0 次:
.*?
- space 后跟除换行字符以外的任何 0+ 个字符,尽可能少
2,
- 文字子串
([a-z])
- 第 1 组:小写字母
.*
- 除换行符以外的任何 0+ 个字符(字符串的其余部分)
$
- 字符串结尾。
一般的模式看起来像
^<MANADATORY_LITERAL>(?:<NON_GREEDY_DOT>(<OPTIONAL_PART>))?<GREEDY_DOT>$
我有一个正则表达式,其中包含强制部分、非贪婪(惰性?)部分、可选部分和最后的非贪婪部分。
<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]))?.*$
^^^
详情
^
- 字符串开头Foo:
- 一些文字(?: .*?2,([a-z]))?
- 匹配 greedily 的可选非捕获组(将至少尝试一次)出现 1 次或 0 次:.*?
- space 后跟除换行字符以外的任何 0+ 个字符,尽可能少2,
- 文字子串([a-z])
- 第 1 组:小写字母
.*
- 除换行符以外的任何 0+ 个字符(字符串的其余部分)$
- 字符串结尾。
一般的模式看起来像
^<MANADATORY_LITERAL>(?:<NON_GREEDY_DOT>(<OPTIONAL_PART>))?<GREEDY_DOT>$