我有一个Java Pattern
,例如\s+(foo|bar)
,可以在空格后找到foo
或bar
的所有匹配项。使用匹配组,我可以提取实际匹配的文本。
Pattern pattern=Pattern.compile("\\s+(foo|bar)");
Matcher matcher = pattern.match(someText);
while(matcher.find()) {
String value = matcher.group(1);
...
}
这适用于类似foo foo bar
的字符串(请注意前面的空格),但它也可以匹配类似foo foo bad
的字符串。如何阻止匹配器匹配不匹配的后续字符运行,或者检测到跳过了字符或没有剩余的字符了?换句话说,我希望整个字符串被匹配为与模式匹配的一系列后续字符串。我怎么能保证呢?
这里的重点是继续通过字符串查找匹配项。我可以轻松地拆分字符串,然后执行其他比较,但是我不希望多次正则表达式传递,数组/列表创建等产生开销。
答案 0 :(得分:2)
用\G
前缀正则表达式。 Pattern
的Javadoc说:
\G
-上一场比赛的结束
当然,在第一场比赛中,“上一场比赛的结束”是输入的开始。
这确保从输入的开头开始,所有正则表达式匹配都将是连续的。并不意味着正则表达式将到达输入的末尾,您必须自己检查一下。
示例
public static void main(String[] args) {
test("abc");
test(" foo foo bar");
test(" foo foo bad");
test(" foo bad foo");
}
static void test(String input) {
System.out.println("'" + input + "'");
int lastEnd = 0;
Matcher m = Pattern.compile("\\G\\s+(foo|bar)").matcher(input);
while (m.find()) {
System.out.printf(" g0='%s' (%d-%d), g1='%s' (%d-%d)%n",
m.group(), m.start(), m.end(),
m.group(1), m.start(1), m.end(1));
lastEnd = m.end();
}
if (lastEnd == input.length())
System.out.println(" OK");
else
System.out.println(" Incomplete: Last match ended at " + lastEnd);
}
输出
'abc'
Incomplete: Last match ended at 0
' foo foo bar'
g0=' foo' (0-4), g1='foo' (1-4)
g0=' foo' (4-8), g1='foo' (5-8)
g0=' bar' (8-12), g1='bar' (9-12)
OK
' foo foo bad'
g0=' foo' (0-4), g1='foo' (1-4)
g0=' foo' (4-8), g1='foo' (5-8)
Incomplete: Last match ended at 8
' foo bad foo'
g0=' foo' (0-4), g1='foo' (1-4)
Incomplete: Last match ended at 4
为了进行比较,在正则表达式中没有\G
时,该代码的输出为:
'abc'
Incomplete: Last match ended at 0
' foo foo bar'
g0=' foo' (0-4), g1='foo' (1-4)
g0=' foo' (4-8), g1='foo' (5-8)
g0=' bar' (8-12), g1='bar' (9-12)
OK
' foo foo bad'
g0=' foo' (0-4), g1='foo' (1-4)
g0=' foo' (4-8), g1='foo' (5-8)
Incomplete: Last match ended at 8
' foo bad foo'
g0=' foo' (0-4), g1='foo' (1-4)
g0=' foo' (8-12), g1='foo' (9-12)
OK
如您所见,最后一个示例将无法检测到跳过了文本bad
。