Go解析gpg --list-keys时正则报不支持Perl语法(?<错误如何解决
问题原因
Go标准库regexp采用RE2正则引擎,不支持Perl兼容正则(PCRE)中的零宽断言语法,你写的(?<=\<)属于正向回顾断言,不在RE2支持范围内,因此编译报错。在线正则测试工具大多默认使用PCRE引擎,所以可以正常匹配。
可行解决方案
1. 替换RE2兼容的正则表达式
无需使用零宽断言,直接用捕获组提取<>内的内容即可,正则改为:
`<([^>]+)>`
该正则逻辑为:匹配<开头,后续所有非>的字符直到遇到>,并将<>中间的内容放入第一个捕获组。
2. 调整代码适配多结果提取
你原有结构体只能存储单个uid,需要修改为切片存储多个邮箱,同时调整解析逻辑遍历所有匹配结果,修改后完整代码如下:
import ( "bytes" "fmt" "os" "os/exec" "regexp" "strings" ) // 修改为切片存储多个匹配到的邮箱 type GPGList struct { Uids []string } //find list keys func Findlistkeys(){ pathexec, err := exec.LookPath("gpg") if err != nil { printError(err) return } cmd := exec.Command(pathexec, "--list-keys") cmdOutput := &bytes.Buffer{} cmd.Stdout = cmdOutput printCommand(cmd) err = cmd.Run() printError(err) output := cmdOutput.Bytes() printOutput(output) gpgList := GPGList{} parseOutput(output, &gpgList) // 按要求格式输出 fmt.Println("{") for _, uid := range gpgList.Uids { fmt.Printf(" {uid : %s},\n", uid) } fmt.Println("}") } func printCommand(cmd *exec.Cmd) { fmt.Printf("==> Executing: %s\n", strings.Join(cmd.Args, " ")) } func printError(err error) { if err != nil { os.Stderr.WriteString(fmt.Sprintf("==> Error: %s\n", err.Error())) } } func printOutput(outs []byte) { if len(outs) > 0 { fmt.Printf("==> Output: %s\n", string(outs)) } } func parseOutput(outs []byte, gpgList *GPGList) { // 使用RE2兼容的正则 uidRegex := regexp.MustCompile(`<([^>]+)>`) // 查找所有匹配项 matches := uidRegex.FindAllSubmatch(outs, -1) for _, match := range matches { if len(match) >= 2 { // 提取第一个捕获组内容,即邮箱 gpgList.Uids = append(gpgList.Uids, string(match[1])) } } }
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

