是否有API方法返回與正則表達式匹配的所有子字符串(可能重疊)?與java正則表達式匹配的所有重疊子串
例如,我有一個文本字符串: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)
算法枚舉和檢查所有的模式與子字符串。
EDIT
不是枚舉所有子串,它是安全使用region(int start, int end)
方法Matcher
。根據單獨提取的子字符串檢查模式可能會改變匹配的結果(例如,如果在模式的開始/結尾處存在非捕獲組或字邊界檢查)。
EDIT 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 + ")");
}
}
}
}
EDIT 4
這裏是這樣做的更好的方式:https://stackoverflow.com/a/11372670/244526
EDIT 5
的JRegex庫支持查找所有重疊的子串匹配的Java正則表達式(雖然似乎沒有在一段時間內更新)。具體而言,documentation on non-breaking search指定:
使用非間斷搜索可以找到一個 圖案的所有可能occureneces,包括那些相交或嵌套。這是 通過使用匹配器的方法proceed()而不是find()來實現
只是通過所有3個或更多字符結果做一個post-regex循環 –
http://regexlib.com/可能是一個很好的地方做一些挖掘。 –
@Ωmega盡我所能,但對反饋沒有用處。乾杯。 –