假设我有一个包含以下内容的字符串:
HelloxxxHelloxxxHello
我编译了一个模式来查找'Hello'
Pattern pattern = Pattern.compile("Hello");
Matcher matcher = pattern.matcher("HelloxxxHelloxxxHello");
它应该找到三个匹配项。我怎样才能知道有多少场比赛呢?
我已经尝试了各种循环和使用matcher.groupCount()
,但它没有工作。
matcher.find()
没有找到所有的匹配,只找到下一个匹配。
long matches = matcher.results().count();
Java 8及更早版本的解决方案
你必须做以下事情。(从Java 9开始,有一个更好的解决方案)
int count = 0;
while (matcher.find())
count++;
Btw, matcher.groupCount()
是完全不同的东西。
完整的示例:
import java.util.regex.*;
class Test {
public static void main(String[] args) {
String hello = "HelloxxxHelloxxxHello";
Pattern pattern = Pattern.compile("Hello");
Matcher matcher = pattern.matcher(hello);
int count = 0;
while (matcher.find())
count++;
System.out.println(count); // prints 3
}
}
处理重叠匹配
当计算aaaa
中aa
的匹配时,上面的代码片段将给出2。
aaaa
aa
aa
获得3个匹配,即这种行为:
aaaa
aa
aa
aa
您必须在索引<start of last match> + 1
处搜索匹配,如下所示:
String hello = "aaaa";
Pattern pattern = Pattern.compile("aa");
Matcher matcher = pattern.matcher(hello);
int count = 0;
int i = 0;
while (matcher.find(i)) {
count++;
i = matcher.start() + 1;
}
System.out.println(count); // prints 3
这应该适用于可能重叠的匹配:
public static void main(String[] args) {
String input = "aaaaaaaa";
String regex = "aa";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
int from = 0;
int count = 0;
while(matcher.find(from)) {
count++;
from = matcher.start() + 1;
}
System.out.println(count);
}
在Java 9中,您可以使用Matcher.results()
long matches = matcher.results().count();
如果您想使用Java 8流并且对while
循环过敏,您可以尝试:
public static int countPattern(String references, Pattern referencePattern) {
Matcher matcher = referencePattern.matcher(references);
return Stream.iterate(0, i -> i + 1)
.filter(i -> !matcher.find())
.findFirst()
.get();
}
声明:这只适用于不相交的匹配。
的例子:
public static void main(String[] args) throws ParseException {
Pattern referencePattern = Pattern.compile("PASSENGER:\d+");
System.out.println(countPattern("[ "PASSENGER:1", "PASSENGER:2", "AIR:1", "AIR:2", "FOP:2" ]", referencePattern));
System.out.println(countPattern("[ "AIR:1", "AIR:2", "FOP:2" ]", referencePattern));
System.out.println(countPattern("[ "AIR:1", "AIR:2", "FOP:2", "PASSENGER:1" ]", referencePattern));
System.out.println(countPattern("[ ]", referencePattern));
}
输出:
2
0
1
0
这是与流不相交匹配的解决方案:
public static int countPattern(String references, Pattern referencePattern) {
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
new Iterator<Integer>() {
Matcher matcher = referencePattern.matcher(references);
int from = 0;
@Override
public boolean hasNext() {
return matcher.find(from);
}
@Override
public Integer next() {
from = matcher.start() + 1;
return 1;
}
},
Spliterator.IMMUTABLE), false).reduce(0, (a, c) -> a + c);
}
使用下面的代码查找正则表达式在您的输入
中找到的匹配次数的计数 Pattern p = Pattern.compile(regex, Pattern.MULTILINE | Pattern.DOTALL);// "regex" here indicates your predefined regex.
Matcher m = p.matcher(pattern); // "pattern" indicates your string to match the pattern against with
boolean b = m.matches();
if(b)
count++;
while (m.find())
count++;
这是一个通用的代码,但不是特定的,定制它以满足您的需要
如有错误请指正