Golang中正则表达式的正确使用方法
Golang中正则表达式的正确使用方法
我正在尝试使用正则表达式解析 ps 命令的输出,但目前无法正常工作。调用 ps 命令时使用了以下参数:
$ ps -eo min_flt,maj_flt,%cpu,%mem,rss,stat,cmd --sort=-maj_flt
示例输出如下:
343 0 0.0 0.0 3936 R ps -eo min_flt,maj_flt,%cpu,%mem,rss,stat,cmd --sort=-maj_flt
以下是我正在使用的正则表达式:
/^(.*?)[\s]+(.*?)[\s]+(.*?)[\s]+(.*?)[\s]+(.*?)[\s]+(.*?)[\s]+(.*?)[\s]+(.*?)$/gm
代码如下:
pattern := /^(.*?)[\s]+(.*?)[\s]+(.*?)[\s]+(.*?)[\s]+(.*?)[\s]+(.*?)[\s]+(.*?)[\s]+(.*?)$/gm
regex, _ := regexp.Compile(pattern)
match := regex.FindStringSubmatch(ps_line_str)
但没有任何匹配项。请注意,该正则表达式模式在 https://regex101.com 上的“Regular Expressions 101”工具中有效,并提供以下匹配信息:
Match 1 0-93 343 0 0.0 0.0 3936 R ps -eo min_flt,maj_flt,%cpu,%mem,rss,stat,cmd --sort=-maj_flt
Group 1 0-3 343
Group 2 9-10 0
Group 3 12-15 0.0
Group 4 17-20 0.0
Group 5 22-26 3936
Group 6 27-28 R
Group 7 32-34 ps
Group 8 35-93 -eo min_flt,maj_flt,%cpu,%mem,rss,stat,cmd --sort=-maj_flt
还有一点信息,当正则表达式减少四个捕获组并且 ps 命令按如下方式调用时,它工作正常:
$ ps -eo min_flt,maj_flt,%mem,cmd --sort=-maj_flt
输出看起来像这样:
1154 0 0.0 ps -eo min_flt,maj_flt,%mem,cmd --sort=-maj_flt
代码像这样:
pattern := `^(.*?)[\s]+(.*?)[\s]+(.*?)[\s]+(.*?)$`
regex, _ := regexp.Compile(pattern)
match := regex.FindStringSubmatch(ps_line_str)
并且匹配会成功找到所有分组。
非常感谢任何帮助。
此致。
更多关于Golang中正则表达式的正确使用方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我发帖太早了,因为我刚刚在 https://regex101.com 网站上找到了答案。他们有一个侧边栏菜单“Flavors”,你可以在那里选择你正在使用的语言。当我将其更改为 Golang 时,正则表达式被更改如下:
^(.*?)[\s]+(.*?)[\s]+(.*?)[\s]+(.*?)[\s]+(.*?)[\s]+(.*?)[\s]+(.*?)[\s]+(.*?)$
现在代码又可以正常工作了。我发布这个后续信息,以防有人遇到类似的问题。
谢谢。
更多关于Golang中正则表达式的正确使用方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中使用正则表达式时,有几个关键点需要注意。你的正则表达式在regex101上有效但在Go中失败,主要是因为Go的regexp包不支持/gm修饰符和某些正则语法。
以下是修正后的代码:
package main
import (
"fmt"
"regexp"
)
func main() {
ps_line_str := "343 0 0.0 0.0 3936 R ps -eo min_flt,maj_flt,%cpu,%mem,rss,stat,cmd --sort=-maj_flt"
// 修正后的正则表达式
pattern := `^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+)$`
regex, err := regexp.Compile(pattern)
if err != nil {
panic(err)
}
match := regex.FindStringSubmatch(ps_line_str)
if match != nil {
fmt.Printf("完整匹配: %s\n", match[0])
for i := 1; i < len(match); i++ {
fmt.Printf("Group %d: %s\n", i, match[i])
}
} else {
fmt.Println("没有匹配")
}
}
输出结果:
完整匹配: 343 0 0.0 0.0 3936 R ps -eo min_flt,maj_flt,%cpu,%mem,rss,stat,cmd --sort=-maj_flt
Group 1: 343
Group 2: 0
Group 3: 0.0
Group 4: 0.0
Group 5: 3936
Group 6: R
Group 7: ps -eo min_flt,maj_flt,%cpu,%mem,rss,stat,cmd --sort=-maj_flt
主要修正点:
- 移除修饰符:Go的
regexp包不支持/gm修饰符,这些需要在模式中明确表示 - 使用原始字符串:使用反引号
`而不是斜杠/ - 简化模式:使用
\S+匹配非空白字符,\s+匹配空白字符 - 处理命令部分:最后一个捕获组使用
.+匹配剩余的所有内容
如果你需要更灵活地处理可变数量的空格,可以使用这个模式:
pattern := `^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+)$`
或者使用更通用的方法处理ps输出:
func parsePSOutput(line string) map[string]string {
pattern := `^(\d+)\s+(\d+)\s+([\d.]+)\s+([\d.]+)\s+(\d+)\s+(\S+)\s+(.+)$`
regex := regexp.MustCompile(pattern)
match := regex.FindStringSubmatch(line)
if match == nil {
return nil
}
return map[string]string{
"min_flt": match[1],
"maj_flt": match[2],
"cpu": match[3],
"mem": match[4],
"rss": match[5],
"stat": match[6],
"cmd": match[7],
}
}
对于错误处理,建议总是检查Compile的返回值:
regex, err := regexp.Compile(pattern)
if err != nil {
// 处理错误
log.Fatalf("无效的正则表达式: %v", err)
}
Go的regexp包使用RE2引擎,不支持一些PCRE特性如回溯引用、前向断言等,但性能更好且保证线性时间匹配。

