我有ping命令的结果有两种方式 - >
1->5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.067/0.078/0.087/0.007 ms
2->5 packets transmitted, 5 received, 0% packet loss, time 801ms
rtt min/avg/max/stddev = 0.019/0.034/0.044/0.010 ms, ipg/ewma 200.318/0.038 ms
这些是两个不同平台中ping命令的结果。 现在,我希望在这两种情况下都能获得avg / stddev的值。 我写了一个正则表达式 -
var latencyPattern = regexp.MustCompile("(round-trip|rtt) .* = (.*)/(.*)/(.*)/(.*) *ms,")
if matches := latencyPattern.FindStringSubmatch(strOutput); len(matches) >= 5{
latency, _ = strconv.ParseFloat(strings.TrimSpace(matches[3]), 64)
jitter, _ = strconv.ParseFloat(strings.TrimSpace(matches[5]), 64)
}
现在这个模式对于ping的第二个结果工作正常(给我0.034和0.01作为结果)。但是对于结果1,它无法找到模式(即给出0.078和0.007)。 如何更改正则表达式以适用于两者?
答案 0 :(得分:2)
定义正则表达式时需要更精确。 .*
过于贪婪,并且可以使用逗号和其他内容进行匹配。
我建议使用
var latencyPattern = regexp.MustCompile(`(round-trip|rtt)\s+\S+\s*=\s*([0-9.]+)/([0-9.]+)/([0-9.]+)/([0-9.]+)\s*ms`)
请参阅regex demo。
package main
import (
"fmt"
"regexp"
"strings"
"strconv"
)
func main() {
strOutput := `1->5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.067/0.078/0.087/0.007 ms
2->5 packets transmitted, 5 received, 0% packet loss, time 801ms
rtt min/avg/max/stddev = 0.019/0.034/0.044/0.010 ms, ipg/ewma 200.318/0.038 ms`
latencyPattern := regexp.MustCompile(`(round-trip|rtt)\s+\S+\s*=\s*([0-9.]+)/([0-9.]+)/([0-9.]+)/([0-9.]+)\s*ms`)
matches := latencyPattern.FindAllStringSubmatch(strOutput, -1)
for _, item := range matches {
latency, _ := strconv.ParseFloat(strings.TrimSpace(item[3]), 64)
jitter, _ := strconv.ParseFloat(strings.TrimSpace(item[5]), 64)
fmt.Printf("AVG = %.3f, STDDEV = %.3f\n", latency, jitter)
}
}
结果:
AVG = 0.078, STDDEV = 0.007
AVG = 0.034, STDDEV = 0.010
模式详情:
(round-trip|rtt)
- round-trip
或rtt
子字符串\s+
- 1+空格\S+
- 1个非空白符号\s*=\s*
- 包含0 +空格的=
([0-9.]+)
- 第1组:第一个数字/
- /
([0-9.]+)
- 第2组:第二个数字/
- /
([0-9.]+)
- 第3组:第三个数字/
- /
([0-9.]+)
- 第4组:第四个数字\s*
- 0+ whitespaces ms
- 子字符串ms
答案 1 :(得分:0)
就个人而言,我会尽可能地简化这一点,特别是因为你不是想要提取所有数据,只是几个部分 - 在两个版本中都方便地使用相同的格式!基本上,在该字符串中,您只关心min/avg/max/stddev = 0.019/0.034/0.044/0.010
:
re := regexp.MustCompile("min/avg/max/stddev = ([0-9./]+)")
sub := re.FindStringSubmatch(input)
parts := strings.Split(sub[1], "/")
fmt.Printf("Avg: %s, StdDev: %s\n", parts[1], parts[3])