java正则表达式性能_译:Java 中的正则表达式性能概述
譯者:Darren Luo
1. 概述
在本快速教程中,我們將展示模式匹配引擎是如何工作的。我們還將介紹在 Java 中優(yōu)化正則表達(dá)式的不同方式。
有關(guān)正則表達(dá)式的的使用介紹,請(qǐng)參閱此文。
2. 模式匹配引擎
java.util.regex 包使用了一種叫做?Nondeterministic Finite Automaton(NFA)(不確定性有窮自動(dòng)機(jī))的模式匹配引擎。它被認(rèn)為是不確定的是因?yàn)樵趯?duì)給定字符串嘗試匹配正則表達(dá)式時(shí),輸入的每個(gè)字符可能針對(duì)正則表達(dá)式的不同部分進(jìn)行多次檢查。
在后臺(tái),上面提到的引擎使用回溯。這種通用算法嘗試用盡所有可能性,知道它宣告失敗。考慮下面的示例可以更好的理解 NFA:
"tra(vel|ce|de)m"
在輸入字符串“travel”時(shí),該引擎首先會(huì)查找“tra”并立即找到它。
在這之后,它將從第四個(gè)字符開始嘗試匹配“vel”。這將匹配上,所以她將繼續(xù)并嘗試匹配”m“。
那將不能匹配,因此,它將回到第四個(gè)字符并搜索”ce“。這次將不再匹配,所以它將再次回到第四個(gè)位置并嘗試匹配”de“。這個(gè)字符串耶不能匹配,因此它將返回輸入字符串的第二個(gè)字符并嘗試搜索另一個(gè)“tra”。
最后一次失敗時(shí),算法將返回失敗。
在上面的簡(jiǎn)單例子里,在嘗試將輸入字符串和正則表達(dá)式匹配時(shí),引擎必須多次回溯。因此,減少回溯次數(shù)時(shí)非常重要的。
3. 優(yōu)化正則表達(dá)式的方法
3.1 避免重新編譯
Java 中的正則表達(dá)式被編譯為內(nèi)部數(shù)據(jù)接口。這個(gè)編譯時(shí)一個(gè)耗時(shí)的過程。
我們每次調(diào)用?String.matches(String regex)?方法時(shí),制定的正則表達(dá)式都會(huì)重新編譯。
if (input.matches(regexPattern)) {
// do something
}
我們可以看到,每次進(jìn)行條件求值時(shí),正則表達(dá)式將被編譯。
要進(jìn)行優(yōu)化,只能首先編譯模式,然后創(chuàng)建一個(gè)?Matcher?來查找值中的匹配:
Pattern pattern = Pattern.compile(regexPattern);
for(String value : values) {
Matcher matcher = pattern.matcher(value);
if (matcher.matches()) {
// do something
}
}
上述優(yōu)化的替代方案時(shí)使用相同的?Matcher?示例及其?reset()?方法:
Pattern pattern = Pattern.compile(regexPattern);
Matcher matcher = pattern.matcher("");
for(String value : values) {
matcher.reset(value);
if (matcher.matches()) {
// do something
}
}
由于?Matcher?不是線程安全的情況,我們必須謹(jǐn)慎使用這種變體。在多線程場(chǎng)景中可能存在危險(xiǎn)。
總而言之,無論哪種情況,我們都保證在任何時(shí)間點(diǎn)都只有一個(gè)?Matcher?用例,可以用?reset?來重用它。對(duì)于這個(gè)例子,重復(fù)使用預(yù)編譯已經(jīng)足夠了。
3.2. 使用替換(Alternation)
正如上一節(jié)我們測(cè)試的那樣,替換使用不當(dāng)可能會(huì)對(duì)性能產(chǎn)生影響。最重要的是將選項(xiàng)放置最可能發(fā)生的前方,這樣能更快的匹配。
此外,我們必須提取提取他們之間的共同模式。下面兩個(gè)是不一樣的:
(travel | trade | trace)
對(duì)比:
tra(vel | de | ce)
后一個(gè)更快,因?yàn)?NFA 將嘗試匹配“tra”,如果沒找到它,則不會(huì)嘗試任何替代方案。
3.3. 捕獲分組(Group)
每次我們捕獲分組時(shí),我們都會(huì)遭受一次小規(guī)模的懲罰。
如果我們需要在分組里捕獲文本,我們應(yīng)該考慮使用非捕獲分組。請(qǐng)用“(?:M)”替代使用“(M)”。
總結(jié)
在這篇短文中,我們簡(jiǎn)要回顧了?NFA?的工作原理。然后,我們通過與扁我們的模式并重用?Matcher?來探索如何優(yōu)化我們正則表達(dá)式的性能。
最后,我們指出我們?cè)谑褂锰鎿Q和分組的一些注意事項(xiàng)。
和往常一樣,可以在 Github 上找到完整的源代碼。
http://www.spring4all.com/article/1479
總結(jié)
以上是生活随笔為你收集整理的java正则表达式性能_译:Java 中的正则表达式性能概述的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 酷狗音乐如何设置手机铃声
- 下一篇: jquery解析java对象数组_Jav