You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写可处理任意顺序多个key=value键值对的正则表达式

适配任意顺序键值对的正则实现方案

核心思路

Go标准库的regexp采用RE2引擎,我们可以将每个需要提取的键值对封装为独立的可选匹配分组,配合惰性匹配跳过无关内容,即可完全不依赖键的出现顺序完成提取。

修正后的正则规则

针对你需要提取的datetime、event、duration三个字段,正则写法如下:

^.*?(?:datetime="(?P<datetime>[^"]*)")?.*?(?:event="(?P<event>[^"]*)")?.*?(?:duration=(?P<duration>\S+))?.*$

规则说明

  • 每个目标键对应一个可选非捕获组(?:匹配规则)?,字段存在就提取值,不存在也不会导致整体匹配失败
  • .*?为惰性匹配,用于跳过当前字段前的任意无关内容,无需关注字段出现顺序
  • 用[^"]*匹配双引号包裹的值,比惰性匹配.*?性能更高,也不会出现越界匹配问题
  • 用\S+匹配无引号的纯数值/纯文本值,匹配到空白字符自动停止

完整可运行代码

package main

import (
	"fmt"
	"regexp"
)

// groupmap 将正则匹配结果转为命名分组的map
func groupmap(s string, r *regexp.Regexp) map[string]string {
	values := r.FindStringSubmatch(s)
	keys := r.SubexpNames()

	d := make(map[string]string)
	for i := 1; i < len(keys); i++ {
		d[keys[i]] = values[i]
	}
	return d
}

func main() {
	input := `extra_data_probably_has_equal_sign_in_it datetime="2021-05-30T11:02:00-09:00" level=info event="event content" duration=0`
	// 顺序无关的正则
	re := regexp.MustCompile(`^.*?(?:datetime="(?P<datetime>[^"]*)")?.*?(?:event="(?P<event>[^"]*)")?.*?(?:duration=(?P<duration>\S+))?.*$`)
	fmt.Println(groupmap(input, re))
}

运行输出:

map[datetime:2021-05-30T11:02:00-09:00 duration:0 event:event content]

扩展说明

如果需要新增提取字段,只需要按照.*?(?:键规则(?P<键名>值规则))?的格式插入正则即可,不需要调整现有匹配逻辑,比如要新增提取level字段,修改正则为:

^.*?(?:datetime="(?P<datetime>[^"]*)")?.*?(?:event="(?P<event>[^"]*)")?.*?(?:duration=(?P<duration>\S+))?.*?(?:level=(?P<level>\S+))?.*$

内容的提问来源于stack exchange,提问作者Haifeng Zhang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 14:15:02