[英]Java Regular Expressions using Pattern and Matcher
我的問題與Java中的正則表達式有關,特別是給定搜索模式的多個匹配。 我需要獲取的所有信息都在1行,它包含一個映射到IP地址的別名(例如SA)。 每個都用逗號分隔。 我需要提取每一個。
SA "239.255.252.1", SB "239.255.252.2", SC "239.255.252.3", SD "239.255.252.4"
我的Reg Ex看起來像這樣:
Pattern alias = Pattern.compile("(\\S+)\\s+\"(\\d+\\.\\d+\\.\\d+\\.\\d+)\"");
Matcher match = alias.matcher(lineInFile)
while(match.find()) {
// do something
}
這可行,但我並不完全滿意,因為自從引入這一小段代碼后,我的程序已經放慢了一點(<1秒)但足以注意到差異。
所以我的問題是,我是否以正確的方式解決這個問題? 是否有更高效或可能輕量級的解決方案,而不需要一個while(匹配)循環? 和/或模式/匹配類?
如果該行可能不包含除別名定義之外的任何內容,則使用.match()
而不是.find()
可能會加快對非匹配的搜索。
我擔心你的代碼看起來非常有效。 這是我的版本:
Matcher match = Pattern
.compile("(\\w+)\\s+\"(\\d+\\.\\d+\\.\\d+\\.\\d+)\"")
.matcher(lineInFile);
while(match.find()) {
//do something
}
有兩個微優化:
實際上,如果你做了很多這樣的處理並且模式永遠不會改變,你應該將編譯后的模式保持為常量:
private static final Pattern PATTERN = Pattern
.compile("(\\w+)\\s+\"(\\d+\\.\\d+\\.\\d+\\.\\d+)\"");
Matcher match = PATTERN.matcher(lineInFile);
while(match.find()) {
//do something
}
更新:我花了一些時間在RegExr上提出了一個更具體的模式,它應該只檢測有效的IP地址作為獎勵。 我知道這很難看,但我的猜測是它非常高效,因為它消除了大部分的回溯:
([A-Z]+)\s*\"((?:1[0-9]{2}|2(?:(?:5[0-5]|[0-9]{2})|[0-9]{1,2})\.)
{3}(?:1[0-9]{2}|2(?:5[0-5]|[0-9]{2})|[0-9]{1,2}))
(為了便於閱讀,所有反斜杠都需要在java中進行轉義,但你可以在RegExr上測試它,因為它與OP的測試字符串一樣)
您可以將正則表達式改進為: "(\\\\S{2})\\\\s+\\"((\\\\d{1,3}\\\\.){3}\\\\d{1,3})\\""
通過更明確地指定IP地址。
嘗試使用StringTokenizer
的性能。 它不使用正則表達式。 (如果您擔心使用遺留類,那么請查看其源代碼並了解它是如何完成的。)
StringTokenizer st = new StringTokenizer(lineInFile, " ,\"");
while(st.hasMoreTokens()){
String key = st.nextToken();
String ip = st.nextToken();
System.out.println(key + " ip: " + ip);
}
我不知道這是否會產生很大的性能優勢,但你也可以先做
string.split(", ") // separate groups
然后
string.split(" ?\"") // separate alias from IP address
在比賽中。
預編譯和重用Pattern對象(IMO)可能是最有效的優化。 模式編譯可能是一個昂貴的步驟。
重用Matcher實例(例如使用reset(CharSequence)
)可能有所幫助,但我懷疑它會有很大的不同。
正則表達式本身無法顯着優化。 一種可能的加速方式是用([0-9\\.]+)
替換(\\d+\\.\\d+\\.\\d+\\.\\d+)
([0-9\\.]+)
。 這可能有所幫助,因為它減少了潛在回溯點的數量......但你需要做一些實驗才能確定。 明顯的缺點是它匹配的是無效IP地址的字符序列。
如果您注意到該段代碼的差異<1秒,那么您的輸入字符串必須包含大約一百萬(或至少大約100k)的條目。 我認為這是一個相當公平的性能,如果不編寫自己的專用解析器,我無法看到如何顯着優化它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.