[英]Find out which group matches in Java regex without linear search?
我有一些以編程方式組裝的巨大正則表達式,就像這樣
(A)|(B)|(C)|...
每個子模式都在其捕獲組中。 當我得到匹配時,如何在不對每個group(i)
進行線性測試的情況下確定哪個組匹配group(i)
看它返回非空字符串?
如果以編程方式生成正則表達式,為什么不以編程方式生成n個單獨的正則表達式並依次測試它們中的每一個? 除非它們共享一個共同的前綴並且Java正則表達式引擎很聰明,否則所有替代方案都會得到測試。
更新:我只是查看了Sun Java源代碼,特別是java.util.regex.Pattern $ Branch.match(),這也簡單地對所有備選方案進行線性搜索,依次嘗試每個備選方案。 使用Branch的其他地方不建議對公共前綴進行任何類型的優化。
您可以使用非捕獲組,而不是:
(A)|(B)|(C)| ...
用。。。來代替
((:A)|(?:?B)|(?:C))
非捕獲組(?:)不會包含在組計數中,但分支的結果將在outer()組中捕獲。
將你的正則表達分為三個:
String[] regexes = new String[] { "pattern1", "pattern2", "pattern3" };
for(int i = 0; i < regexes.length; i++) {
Pattern pattern = Pattern.compile(regexes[i]);
Matcher matcher = pattern.matcher(inputStr);
if(matcher.matches()) {
//process, optionally break out of loop
}
}
public int getMatchedGroupIndex(Matcher matcher) {
int index = -1;
for(int i = 0; i < matcher.groupCount(); i++) {
if(matcher.group(i) != null && matcher.group(i).trim().length() > 0) {
index = i;
}
}
return index;
}
替代方案是:
for(int i = 0; i < matcher.groupCount(); i++) {
if(matcher.group(i) != null && matcher.group(i).trim().length() > 0) {
//process, optionally break out of loop
}
}
我認為你不能繞過線性搜索,但是你可以通過使用start(int)
而不是group(int)
來提高效率。
static int getMatchedGroupIndex(Matcher m)
{
int index = -1;
for (int i = 1, n = m.groupCount(); i <= n; i++)
{
if ( (index = m.start(i)) != -1 )
{
break;
}
}
return index;
}
這樣,您只需查詢表示其起始索引的int
值,而不是為每個組生成子字符串。
從各種評論來看,似乎簡單的答案是“不”,並且使用單獨的正則表達式是一個更好的主意。 要改進該方法,您可能需要在生成它們時找出常見的模式前綴,或者使用您自己的正則表達式(或其他)模式匹配引擎。 但在您完成所有這些工作之前, 您需要確保這是您系統中的一個重要瓶頸。 換句話說,對它進行基准測試,看看性能是否可以接受真實的輸入數據,如果不是配置文件,則可以看到真正的瓶頸所在。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.