2010-07-06 113 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