You need to enable JavaScript to run this app. Go解析gpg --list-keys时正则报不支持Perl语法(?<错误如何解决
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 19:06:05