是否有返回匹配正则表达式的(可能重叠的)的子串的API方法?
例如,我有一个文本串: String t = 04/31 412-555-1235;
和我有一个图案: Pattern p = new Pattern("\\d\\d+");
匹配的两个或多个字符的字符串。
我得到的匹配为:04,31,412,555,1235。
我如何获得重叠的比赛吗?
我想要的代码返回:04,31,41,412,12,55,555,55,12,123,1235,23,235,35。
理论上,应该可以-有一个明显的O(n^2)
算法枚举和检查所有针对模式的子字符串。
编辑
而不是枚举所有子串,它是使用更安全的region(int start, int end)
方法在Matcher
。 检查对一个单独的,提取的子模式可能改变匹配的结果(例如,如果有在图案的开始/结束的非捕获组或字边界检查)。
编辑2
事实上,目前还不清楚是否region()
做你所期望的零宽度匹配。 该规范是模糊的,实验产生令人失望的结果。
例如:
String line = "xx90xx";
String pat = "\\b90\\b";
System.out.println(Pattern.compile(pat).matcher(line).find()); // prints false
for (int i = 0; i < line.length(); ++i) {
for (int j = i + 1; j <= line.length(); ++j) {
Matcher m = Pattern.compile(pat).matcher(line).region(i, j);
if (m.find() && m.group().size == (j - i)) {
System.out.println(m.group() + " (" + i + ", " + j + ")"); // prints 90 (2, 4)
}
}
}
我不知道最好的解决方法是什么。 一种方法是采取的一个子line
和垫用适当的边界字符检查是否之前pat
相匹配。
编辑3
这里是我想出了一个完整的解决方案。 它可以在原来的正则表达式处理零宽度的图案,边界等。 它看起来通过文本字符串,并检查正则表达式是否只在通过填充与开头和结尾通配符适当数量的图案中的特定位置相匹配的所有子串。 这似乎为我试过情况下工作 - 虽然我没有做过广泛的测试。 这肯定是比它可能效率较低。
public static void allMatches(String text, String regex)
{
for (int i = 0; i < text.length(); ++i) {
for (int j = i + 1; j <= text.length(); ++j) {
String positionSpecificPattern = "((?<=^.{"+i+"})("+regex+")(?=.{"+(text.length() - j)+"}$))";
Matcher m = Pattern.compile(positionSpecificPattern).matcher(text);
if (m.find())
{
System.out.println("Match found: \"" + (m.group()) + "\" at position [" + i + ", " + j + ")");
}
}
}
}
编辑4
下面是这样做的更好的办法: https://stackoverflow.com/a/11372670/244526
编辑5
该JRegex库支持查找所有重叠的子匹配一个Java正则表达式(虽然它似乎没有在一段时间更新)。 具体而言, 在非打破搜索文件规定:
使用非中断搜索,你可以找到一个模式的所有可能的occureneces,包括那些交叉或嵌套。 这是通过使用匹配器的方法进行()代替find()方法实现