我有一個輸入字符串。將字符串與多個正則表達式匹配
我想如何有效地將這個字符串與多個正則表達式進行匹配。
Example Input: ABCD
我想對陣這些REG-EX模式,並返回true
如果其中至少有一個匹配:
[a-zA-Z]{3}
^[^\\d].*
([\\w&&[^b]])*
我不知道如何來匹配多個模式一次。有人能告訴我我們如何有效地做到這一點?
我有一個輸入字符串。將字符串與多個正則表達式匹配
我想如何有效地將這個字符串與多個正則表達式進行匹配。
Example Input: ABCD
我想對陣這些REG-EX模式,並返回true
如果其中至少有一個匹配:
[a-zA-Z]{3}
^[^\\d].*
([\\w&&[^b]])*
我不知道如何來匹配多個模式一次。有人能告訴我我們如何有效地做到這一點?
如果您只有幾個正則表達式,它們都是已知的在編譯的時候,這就足夠了:
private static final Pattern
rx1 = Pattern.compile("..."),
rx2 = Pattern.compile("..."),
...;
return rx1.matcher(s).matches() || rx2.matcher(s).matches() || ...;
如果有更多的,或者他們被加載在運行時,然後使用一組模式:
final List<Pattern> rxs = new ArrayList<>();
for (Pattern rx : rxs) if (rx.matcher(input).matches()) return true;
return false;
我不知道什麼effectively
手段,但如果它是關於性能,你想查了很多串,我會去爲這個
...
static Pattern p1 = Pattern.compile("[a-zA-Z]{3}");
static Pattern p2 = Pattern.compile("^[^\\d].*");
static Pattern p3 = Pattern.compile("([\\w&&[^b]])*");
public static boolean test(String s){
return p1.matcher(s).matches ? true:
p2.matcher(s).matches ? true:
p3.matcher(s).matches;
}
我不知道它將如何影響性能,但將它們與|
合併成一個正則表達式也可能有所幫助。
這重新邏輯or或缺少括號。爲什麼不使用'p1.matcher(s).matches()|| p2.matcher(s).matches()|| p3.matcher(s).matches()' – kratenko
你是對的。我不知道4年前我在想什麼。 – NeplatnyUdaj
爲了避免重新創建Pattern和Matcher類的實例,您可以創建其中的一個並重用它們。要重用Matcher
課程,您可以使用reset(newInput)
方法。 警告:此方法不是線程安全的。只有當你能保證只有一個線程能夠使用這個方法時才使用它,否則爲每個方法調用創建一個單獨的Matcher實例。
這是可能的代碼示例
private static Matcher m1 = Pattern.compile("regex1").matcher("");
private static Matcher m2 = Pattern.compile("regex2").matcher("");
private static Matcher m3 = Pattern.compile("regex3").matcher("");
public boolean matchesAtLeastOneRegex(String input) {
return m1.reset(input).matches()
|| m2.reset(input).matches()
|| m3.reset(input).matches();
}
「Matcher」存在的全部目的是每次創建它以保持單個匹配動作的狀態。你的代碼不是線程安全的。 –
@MarkoTopolnik確實。感謝您指出了這一點。在一個線程環境中,重置Matcher似乎沒有什麼比重新創建它快,所以決定在我的答案中提到它。希望我的編輯能讓我的回答更好。 – Pshemo
這是一個替代方案。 請注意,這不做的一件事是按特定順序返回它們。但是可以通過以m.start()進行排序來實現。
private static HashMap<String, String> regs = new HashMap<String, String>();
...
regs.put("COMMA", ",");
regs.put("ID", "[a-z][a-zA-Z0-9]*");
regs.put("SEMI", ";");
regs.put("GETS", ":=");
regs.put("DOT", "\\.");
for (HashMap.Entry<String, String> entry : regs.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
Matcher m = Pattern.compile(value).matcher("program var a, b, c; begin a := 0; end.");
boolean f = m.find();
while(f)
{
System.out.println(key);
System.out.print(m.group() + " ");
System.out.print(m.start() + " ");
System.out.println(m.end());
f = m.find();
}
}
}
就像是在(Running multiple regex patterns on String)解釋,最好是每個正則表達式串聯到一個大的正則表達式,比運行匹配唯一的一個。這是一個很大的改進,你經常重用正則表達式。
你的問題不清楚(至少對我而言)。有效的意思是什麼?你想檢查輸入是否匹配所有正則表達式,或者只有一個是足夠的?你可以在輸入期望的輸出旁包含嗎? – Pshemo
我認爲,首先,你應該用自然語言來定義你想要匹配的字符序列。你的例子不讓我們提取任何模式。或者,最好的是,這裏的模式最符合您的輸入:「ABCD」。 –
你想實現什麼? – wumpz