2017-09-14 25 views
5

我想解析使用正則表達式在Java8中的traceroute結果。正則表達式來捕獲跟蹤與Java8中的組

我正在使用下面的正則表達式來識別組。

^(\\d*).*[AS(\\d*)]?\\s+([\\w+\\.]+)\\s+\\(([\\d+\\.]+)\\)[\\s+(\\d+\\.\\d+)\\s+ms]+ 

,我需要解析了一些示例行:

1 10.33.128.1 (10.33.128.1) 4.452 ms 3.459 ms 3.474 ms 
6 * [AS3356] 4.68.72.218 (4.68.72.218) 12.432 ms 11.819 ms 
* 4.68.72.218 (4.68.72.218) 12.432 ms 11.819 ms 
    61.182.180.62 (61.182.180.62) 175.300 ms 203.001 ms 

我要提取的跳數(如果有的話),ASN(如果可用),主機名,IP和時間

但與上述正則表達式匹配的字符串1,2和4這是我想要的,但只給我跳,主機和ASN。

我的代碼是這樣的:

Pattern hop_pattern = Pattern.compile(
     "^(\\d*).*[AS(\\d*)]?\\s+([\\w+\\.]+)\\s+\\(([\\d+\\.]+)\\)[\\s+(\\d+\\.\\d+)\\s+ms]+") 
Matcher m = hop_pattern.matcher(target); 

while(m.find()) { 
    System.out.println("count: " + m.groupCount()); 
    for(int i = 1; i < m.groupCount() + 1; i++) { 
     System.out.println(i + "->" + m.group(i)); 
    } 
} 

,我需要解析了一些示例行:

1 10.33.128.1(10.33.128.1)4.452毫秒3.459毫秒3.474毫秒
6 * [AS3356] 4.68.72.218(4.68.72.218)12.432毫秒11.819毫秒
* 4.68.72.218(4.68.72.218)12.432毫秒11.819毫秒
61.182.180.62(61.182.180.62)175.300毫秒203.001毫秒

我要提取的跳數(如果有的話),ASN(如果可用),主機名,IP和時間

但上述正則表達式,它的串1,2相匹配,和4這是我想要的,但只給了我跳,主機和ASN。

我的代碼是這樣的:

Pattern hop_pattern = Pattern.compile(
      "^(\\d*).*[AS(\\d*)]?\\s+([\\w+\\.]+)\\s+\\(([\\d+\\.]+)\\)[\\s+(\\d+\\.\\d+)\\s+ms]+") 
    Matcher m = hop_pattern.matcher(target); 

    while(m.find()) { 
     System.out.println("count: " + m.groupCount()); 
     for(int i = 1; i < m.groupCount() + 1; i++) { 
      System.out.println(i + "->" + m.group(i)); 
     } 
    } 

我不知道,如果事情是錯誤的代碼或正則表達式本身。感謝幫助!

更新:一些例子和輸出示例

1 [AS0] 10.200.200.200(10.200.200.200)37.526毫秒35.793毫秒37.728毫秒
預期輸出: 一跳:1 ASN:0 主機名:10.200.200.200 IP:10.200.200.200 時間:[37.526,35.793,37.728]

2 [AS0] scsc-usr-13500-02-eth1-07.xyz.com(10.96.15.3)37.927毫秒36.122 ms *
Ex pected輸出: 一跳:2 ASN:0 主機名:scsc-usr-13500-02-eth1-07.xyz.com IP:10.96.15.3 時間:[37.927,36.122]

我我不確定代碼或正則表達式本身是否有問題。感謝幫助!

+0

您是否期望完整的行被打印到控制檯。完整的行是一個匹配項,但您循環遍歷組而不是打印完整行。 –

+3

你可以在這個例子中添加一個你預期提取的樣本嗎? –

+3

@Akur馬上跳出來的問題是你沒有在你的正則表達式中逃脫'['和']'。另外,[AS ...]匹配之前的'。*'會吞噬[AS ...]部分,因爲'*'是貪婪的。但爲了給你一個完整的答案,我們需要確切地知道你想要的輸出是什麼。 – Misha

回答

2

回答

第1部分

爲了捕捉你要找的一切,你需要使用兩個獨立的正則表達式。這樣做的原因是正則表達式將只捕獲最後組找到符合條件,你必須在你的traceroute的結果(例如4.452 ms3.459 ms,並且3.474 ms在你的第一行)多

爲了理解哪些組正在被捕獲,您可以使用以下正則表達式(它是PCRE並且不能在Java中工作,但它可以清楚地指示捕獲哪個組)。

This code can be seen in use here

^(?P<hop>\d+)?[\h*]*(?:\[AS(?<ASN>\d*)\])?\h+(?<hostname>[\w\.]+)\h+\((?<ip>[\d+\.]+)\)\h+(?<times>.*?)\h*$ 

有輕微的修改,上述正則表達式可以在Java中使用(水平空白\h和命名捕捉組(?<name>...)在Java中的正則表達式中不支持,據我所知)。

This code can be seen in use here

^(\d+)?[\ \t*]*(?:\[AS(\d*)\])?[\ \t]+([\w\.]+)[\ \t]+\(([\d+\.]+)\)[\ \t]+(.*?)[\ \t]*$ 

注意:兩個全球g和多線m改性劑使用。


第2部分

運行你部分捕捉的時候,這第二個正規表達式1收集的所有時間列表。

This code can be seen in user here

([\d.]+) 





結果

第1部分

輸入

1 10.33.128.1 (10.33.128.1) 4.452 ms 3.459 ms 3.474 ms 
6 * [AS3356] 4.68.72.218 (4.68.72.218) 12.432 ms 11.819 ms 
* 4.68.72.218 (4.68.72.218) 12.432 ms 11.819 ms 
    61.182.180.62 (61.182.180.62) 175.300 ms 203.001 ms 

輸出

匹配1

  • 全場比賽0-60 1 10.33.128.1 (10.33.128.1) 4.452 ms 3.459 ms 3.474 ms
  • 組1. 1
  • 組3. 10.33.128.1
  • 第4組。10.33.128.1
  • 組5. 4.452 ms 3.459 ms 3.474 ms

第2場

  • 全場比賽61-124 6 * [AS3356] 4.68.72.218 (4.68.72.218) 12.432 ms 11.819 ms
  • 組1. 6
  • 組2 3356
  • 組3。 4.68.72.218
  • 組4. 4.68.72.218
  • 組5. 12.432 ms 11.819 ms

匹配3

  • 全場比賽125-177 * 4.68.72.218 (4.68.72.218) 12.432 ms 11.819 ms
  • 組3. 4.68.72.218
  • 組4. 4.68.72.218
  • 組5. 12.432 ms 11.819 ms

匹配4

  • 全場比賽178-232 61.182.180.62 (61.182.180.62) 175.300 ms 203.001 ms
  • 組3 61.182.180.62
  • 組4 61.182.180.62
  • 組5 175.300 ms 203.001 ms

第2部分

輸入

4.452 ms 3.459 ms 3.474 ms 

輸出

匹配1

  • 全場比賽0-5 4.452
  • 組1. 4.452

第2場

  • 全場比賽10-15 3.459
  • 組1。3.459

匹配3

  • 全場比賽20-25 3.474
  • 組1. 3.474





編輯

謝謝Casimir et Hippolyte對指出的Java確實允許命名捕捉組其他正則表達式的口味做的。

這裏是自從Java不支持命名捕獲組(?<name>...)

This regex can be seen in use here

^(?P<hop>\d+)?[\t *]*(?:\[AS(?<ASN>\d*)\])?[\t ]+(?<hostname>[\w\.]+)[\t ]+\((?<ip>[\d+\.]+)\)[\t ]+(?<times>.*?)[\t ]*$ 
+0

命名捕捉也可以在Java中使用。 –

+0

@CasimiretHippolyte謝謝,我已經相應地編輯了我的帖子。 – ctwheels

+1

非常感謝你。我使用Java進行了一些小改動。這裏是表達式我使用了'Pattern hop_pattern = Pattern.compile( 「^(? \\ d +)?[\\ W] +(?:\\ [AS(? \\ d *)\\]) ?[\\ s] +(? [\\ S \\。] +)[\\ s] + \\((?? [\\ d + \\。] +)\\)[\\ s] +(?。*?)[\\ s] * $「);' – Ankur

1

我在準備一個非常類似的解決方案,但嘗試過一次捕獲一切更新的正則表達式。

現在,您可以看到here

^(?P<hop>\d+)?[\W]*(?:\[AS(?<ASN>\d*)\])?[\t ]+(?<hostname>[\w\.]+)[\t ]+\((?<ip>[\d+\.]+)\)[\t ]+(?<times>(?:(?:[\t ]*(\d+\.\d+)\sms)\s*(?:(\d+\.\d+)\sms[\t ]*)(?:(\d+\.\d+)\sms[\t ]+)?))[\t ]*$

更新:由於\ H不存在於Java中,我替換爲[\噸] \小時,預期對於其中I優選\ W一個實例。
附錄:由於@Holger指出,\^h 是Java提供8

然而,它最有可能還是比較容易處理的時間在一個額外的步驟,如圖@ctwheels出色答卷。

+0

'\ h'在Java中不存在,您必須找到一個解決方法來模仿它。你也不需要逃避角色類中的點。您可以使用此站點對Java正則表達式進行更多測試:http://www.regexplanet。com –

+0

謝謝@Cimimir et Hippolyte。這是一個艱難的,但很有趣。 – wp78de

+1

@Casimir et Hippolyte:從[java.util.regex.Pattern'的文檔](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html#預編譯):'\ h \t水平空格字符:[\ t \ xA0 \ u1680 \ u180e \ u2000- \ u2002f \ u205f \ u3000]' – Holger