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

Ank*_*kur 5 java regex java-8

我试图使用Regex解析Java8中的traceroute结果.

我使用下面的正则表达式来识别组.

^(\\d*).*[AS(\\d*)]?\\s+([\\w+\\.]+)\\s+\\(([\\d+\\.]+)\\)[\\s+(\\d+\\.\\d+)\\s+ms]+
Run Code Online (Sandbox Code Playgroud)

我需要解析的一些示例行是:

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
Run Code Online (Sandbox Code Playgroud)

我想提取跳数(如果可用),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));
    }
}
Run Code Online (Sandbox Code Playgroud)

我需要解析的一些示例行是:

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));
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

更新:一些示例和示例输出

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

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

ctw*_*els 2

回答

第1部分

为了捕获您正在寻找的所有内容,您需要使用两个单独的正则表达式。原因是正则表达式只会捕获它找到的最后一个与条件匹配的组,并且您的跟踪路由结果中有多次(例如4.452 ms3.459 ms第一3.474 ms行中)。

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

这段代码可以在这里看到使用情况

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

经过轻微修改,上述正则表达式可以在 Java 中使用(据我所知,Java 正则表达式不支持水平空格\h和命名捕获组)。(?<name>...)

这段代码可以在这里看到使用情况

^(\d+)?[\ \t*]*(?:\[AS(\d*)\])?[\ \t]+([\w\.]+)[\ \t]+\(([\d+\.]+)\)[\ \t]+(.*?)[\ \t]*$
Run Code Online (Sandbox Code Playgroud)

注意:全局修饰符g和多行修饰符m都可以使用。


第2部分

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

这段代码可以在用户这里看到

([\d.]+)
Run Code Online (Sandbox Code Playgroud)





结果

第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
Run Code Online (Sandbox Code Playgroud)

输出

比赛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-23261.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 
Run Code Online (Sandbox Code Playgroud)

输出

比赛1

  • 全场比赛0-54.452
  • 第 1 组。4.452

比赛2

  • 全场比赛10-15 3.459
  • 第 1 组。3.459

比赛3

  • 全场比赛20-25 3.474
  • 第 1 组。3.474





编辑

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

这是更新的正则表达式,因为 Java 确实支持命名捕获组(?<name>...)

这个正则表达式可以在这里看到使用

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