正则表达式使用Java8捕获traceroute中的组

时间:2017-09-14 16:47:08

标签: java regex java-8

我正在尝试使用Regex解析Java8中的traceroute结果。

我使用以下正则表达式来识别群组。

^(\\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 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 [AS0] 10.200.200.200(10.200.200.200)37.526 ms 35.793 ms 37.728 ms
  预期产出:   跳: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 ms 36.122 ms *
  预期产出:   跳:2   asn:0   主机名:scsc-usr-13500-02-eth1-07.xyz.com   ip:10.96.15.3   时间:[37.927,36.122]

我不确定代码或正则表达式本身是否有问题。谢谢你的帮助!

2 个答案:

答案 0 :(得分:2)

答案

第1部分

为了捕捉您正在寻找的所有内容,您需要使用两个单独的正则表达式。这样做的原因是正则表达式只捕获它找到的符合条件的最后组,并且您的traceroute结果中有多个(例如4.452 ms,{ {1}},以及第一行中的3.459 ms

为了理解正在捕获哪些组,您可以使用以下正则表达式(它是PCRE并且不会在Java中工作,但它可以清楚地指示正在捕获哪个组)。< / p>

This code can be seen in use here

3.474 ms

稍作修改,上面的正则表达式可以在Java中使用(水平空白^(?P<hop>\d+)?[\h*]*(?:\[AS(?<ASN>\d*)\])?\h+(?<hostname>[\w\.]+)\h+\((?<ip>[\d+\.]+)\)\h+(?<times>.*?)\h*$ ,并且在我所知道的Java正则表达式中不支持命名捕获组\h

This code can be seen in use here

(?<name>...)

注意:使用全局^(\d+)?[\ \t*]*(?:\[AS(\d*)\])?[\ \t]+([\w\.]+)[\ \t]+\(([\d+\.]+)\)[\ \t]+(.*?)[\ \t]*$ 和多行g修饰符。

第2部分

第1部分中捕获的上运行第二个正则表达式,以收集所有时间的列表。

This code can be seen in user here

m



结果

第1部分

输入

([\d.]+)

输出

匹配1

  • 完全匹配0-60 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组1 10.33.128.1 (10.33.128.1) 4.452 ms 3.459 ms 3.474 ms
  • 第3组。1
  • 第4组10.33.128.1
  • 第5组10.33.128.1

匹配2

  • 完全匹配61-124 4.452 ms 3.459 ms 3.474 ms
  • 第1组6 * [AS3356] 4.68.72.218 (4.68.72.218) 12.432 ms 11.819 ms
  • 第2组。6
  • 第3组。3356
  • 第4组4.68.72.218
  • 第5组4.68.72.218

匹配3

  • 完全匹配125-177 12.432 ms 11.819 ms
  • 第3组。* 4.68.72.218 (4.68.72.218) 12.432 ms 11.819 ms
  • 第4组4.68.72.218
  • 第5组4.68.72.218

匹配4

  • 完全匹配178-232 12.432 ms 11.819 ms
  • 第3组。61.182.180.62 (61.182.180.62) 175.300 ms 203.001 ms
  • 第4组61.182.180.62
  • 第5组61.182.180.62

第2部分

输入

175.300 ms  203.001 ms

输出

匹配1

  • 完全匹配0-5 4.452 ms 3.459 ms 3.474 ms
  • 第1组4.452

匹配2

  • 完全匹配10-15 4.452
  • 第1组3.459

匹配3

  • 完全匹配20-25 3.459
  • 第1组3.474



编辑

感谢Casimir et Hippolyte指出Java确实允许命名捕获组像其他正则表达式一样。

这是一个更新的正则表达式,因为Java支持命名捕获组3.474

This regex can be seen in use here

(?<name>...)

答案 1 :(得分: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中不存在,我用[\ t]替换了\ h,期望我喜欢的一个实例\ W。
附录:正如@Holger所述,\ h 在Java 8中可用。

然而,如@ctwheels出色的答案所示,它可能更容易在额外的步骤中处理时间。