2010-07-06 115 views
2

我需要添加到我們的日誌管理解決方案中的Radius消息有非常統一的一組數據。該產品提供了使用正則表達式以幾種形式提取各種數據的功能。使用幾個可重複捕獲組的正則表達式

1)個人對每片數據正則表達式你想使用捕捉組拉出

<data 1 = regex statement> 
    <data 2 = different regex statement>  
    <data 2 = yet another regex statement> 

2)單數正則表達式

<group = regex statement with capture groups> 
     <data 1 = capture group[X] 
     <data 2 = capture group[Y] 
     <data 3 = capture group[Z] 
    </group> 

<158>Jul 6 14:33:00 radius/10.10.100.12 radius: 07/06/2010 14:33:00 AP1A-BLAH (10.10.10.10) - 6191/Wireless - IEEE 802.11: abc1234 - Access-Accept (AP: 000102030405/SSID: bork/Client: 050403020100) 

欲拔出的幾個位數據,所有這些都在空間之間。沿着以下線的東西似乎並不高效:

(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s 

因此,鑑於以上數據,什麼是最有效的Java正則表達式,將抓住每場一組的空間之間,並把它變成一個捕獲組?

+2

爲什麼不是那個正則表達式看起來有效?你有性能問題嗎? – 2010-07-06 19:18:45

+0

幾次重複同一部分的正則表達式(在本例中爲29)似乎不是最好的選擇。我沒有做過這麼一個統一的重複,所以我不確定它是否可以縮短。 – Chris 2010-07-06 19:51:44

+0

29組?你應該看看使用'split()',因爲@蒂姆的第二個答案建議。 – 2010-07-07 03:02:30

回答

2

你能更具體:

(\S*)\s(\S*)\s(\S*)\s(\S*)\s(\S*)\s(\S*)\s 

\S一個非空格字符匹配 - 這使得正則表達式避免回溯更高效,它允許正則表達式失敗,如果輸入不適合快該模式。

即,當將正則表達式應用於字符串Jul 6 14:33:00 radius/10.10.100.12 radius: 07/06/2010時,需要正則表達式引擎2116來查明它不能匹配。上面的正則表達式在168個步驟中失敗。

Alan Moore建議使用(\S*+)\s(\S*+)\s(\S*+)\s(\S*+)\s(\S*+)\s(\S*+)\s會導致另一個改進 - 現在正則表達式在24步內失敗(比最初的正則表達式快近百倍)。

如果匹配成功,Alan和我的解決方案是等價的,你的正則表達式慢10倍左右。

+0

你可以更進一步,讓所有的量詞都具有所有格,即'(\ S * +)'。你不能比這更有效率。 – 2010-07-06 19:28:23

1

我只想到其他的東西 - 爲什麼不簡單地將字符串拆分爲空白?

String[] splitArray = subjectString.split("\\s"); 
+0

我不能做到這一點的唯一原因是我提供的界面是正則表達式,不包括做這種有趣的事情的能力。第一個答案是完美的 - 正則表達式在處理大量日誌時應該足夠高效。 – Chris 2010-07-07 16:08:36