Regex使用Java8捕获traceroute中的组

Regex使用Java8捕获traceroute中的组,java,regex,java-8,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.2

我正在尝试使用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,这是我想要的,但只给我hop、host和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));
    }
}
    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));
        }
    }
Pattern-hop\u Pattern=Pattern.compile(
“^(\\d*)..[AS(\\d*)]?\\s+([\\w+\\.]+)\\s+\([\\d+\.]+)\\)[\\s+(\\d+\.\\d+\\s+ms]+”)
匹配器m=跳跃模式。匹配器(目标);
while(m.find()){
System.out.println(“count:+m.groupCount());
对于(int i=1;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
110.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,这是我想要的,但只给我hop、host和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));
    }
}
    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));
        }
    }
Pattern-hop\u Pattern=Pattern.compile(
“^(\\d*)..[AS(\\d*)]?\\s+([\\w+\\.]+)\\s+\([\\d+\.]+)\\)[\\s+(\\d+\.\\d+\\s+ms]+”)
匹配器m=跳跃模式。匹配器(目标);
while(m.find()){
System.out.println(“count:+m.groupCount());
对于(int i=1;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 ms 36.122 ms*
预期产出: 跳:2 asn:0 主机名:scsc-usr-13500-02-eth1-07.xyz.com ip:10.96.15.3 时间:[37.927,36.122]

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

答复 第一部分 为了捕获所需的所有内容,需要使用两个单独的正则表达式。原因是正则表达式只会捕获它找到的与标准匹配的最后一个组,并且您在跟踪路由结果中有多次(例如,第一行中的
4.452 ms
3.459 ms
,以及
3.474 ms

为了理解捕获的是哪些组,您可以使用以下正则表达式(它是PCRE,在Java中不起作用,但它可以清楚地指示捕获的是哪个组)

注意:同时使用全局
g
和多行
m
修饰符


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





结果 第一部分 输入 输出 匹配1

  • 完全匹配0-60
    110.33.128.1(10.33.128.1)4.452 ms 3.459 ms 3.474 ms
  • 第一组<代码>1
  • 第3组<代码>10.33.128.1
  • 第4组<代码>10.33.128.1
  • 第5组<代码>4.452毫秒3.459毫秒3.474毫秒
第二场比赛

  • 完全匹配61-124
    6*[AS3356]4.68.72.218(4.68.72.218)12.432 ms 11.819 ms
  • 第一组<代码>6
  • 第2组。
    3356
  • 第3组<代码>4.68.72.218
  • 第4组<代码>4.68.72.218
  • 第5组<代码>12.432毫秒11.819毫秒
第三场比赛

  • 完全匹配125-177
    *4.68.72.218(4.68.72.218)12.432毫秒11.819毫秒
  • 第3组<代码>4.68.72.218
  • 第4组<代码>4.68.72.218
  • 第5组<代码>12.432毫秒11.819毫秒
第四场比赛

  • 完全匹配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毫秒203.001毫秒

第二部分 输入 输出 匹配1

  • 完全匹配0-5
    4.452
  • 第一组<代码>4.452
第二场比赛

  • 完全匹配10-15
    3.459
  • 第一组<代码>3.459
第三场比赛

  • 完全匹配20-25
    3.474
  • 第一组<代码>3.474




编辑 感谢您指出Java确实像其他正则表达式一样允许命名捕获组

这是一个更新的正则表达式,因为Java确实支持命名捕获组
(?…)

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

我准备了一个非常类似的解决方案,但试图立即捕获所有内容

正如你所看到的,它现在起作用了

^(?p\d+)?[\W]*(?:\[AS(?\d*)\)?[\t]+(?[\W\.]+)[\t]+\((?[\d+\.]+)[\t]+(?:(?:[\t]*(\d+.\d+\sms)\s*(?:(\d+.\d+\sms[\t]*)(?:(?:(\d+.\d+.\d+.\d+\sms[\d+))))[\t]*)(?:(?:(?:(\d+.\d+.\d+.\d+\sms[\d+)))))))[\t]+)[\t]

更新:由于Java中不存在\h,我将\h替换为[\t],除了一个我更喜欢的实例之外。
附录:如@Holger所述,Java 8中提供了\h

然而,在一个额外的步骤中处理时间可能更容易
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
4.452 ms  3.459 ms  3.474 ms 
^(?P<hop>\d+)?[\t *]*(?:\[AS(?<ASN>\d*)\])?[\t ]+(?<hostname>[\w\.]+)[\t ]+\((?<ip>[\d+\.]+)\)[\t ]+(?<times>.*?)[\t ]*$