【问题标题】:Regex handle multiple "key=value" pairs in random order正则表达式以随机顺序处理多个“key=value”对
【发布时间】:2021-10-27 18:36:51
【问题描述】:

我有一条消息包含标头和有效负载,例如“header payload_key1=value1 payloadkey2=value2”。标头根据特定协议和key=value 模式中的有效负载而有所不同,但键可以按任何顺序排列,因此我更喜欢使用正则表达式而不是基于分隔符的拆分。我正在使用下面的正则表达式来解析有序的字符串,任何人都可以帮助编写一个正则表达式来处理像datetime, event and duration 这样的随机顺序键值对以不同的顺序?

package main

import (
    "fmt";
    "regexp"
)

// code from stackoverflow
func groupmap(s string, r *regexp.Regexp) map[string]string {
values := r.FindStringSubmatch(s)
keys := r.SubexpNames()

// create map
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>.*?)"\sevent=(?P<event>.*?)\s\sduration=(?P<duration>.*?)\s`)
    fmt.Println(groupmap(s, re))
}

【问题讨论】:

  • 把它分成两部分。首先,将字符串拆分为key=value 对。然后在第一个= 上拆分每一对。解析很复杂,因为您引用了包含空格的值。
  • 嗨@Schwern。在我的消息中,它包含两部分:标头和有效负载。键值对在payload中,如果使用split,我必须先将header和payload分开。
  • 您要提取每个键的值,还是验证所有键=值对都存在?
  • 在正则表达式中提取键值对并指定键名,如果有额外的键值对我不担心
  • @HaifengZhang 通过一步一步来简化它。编写一个正则表达式来剥离标题。然后将其拆分为key=value 对的列表。然后在= 上拆分每一对并将它们粘贴到地图中。这些值可以转义引号吗? key="val\"ue"?

标签: regex go


【解决方案1】:

最简单的方法是通过这个正则表达式分割空格,但仅限于那些不在引号内的:

` +(?=(?:(?:[^"]*"){2})*[^"]*$)`

live demo

这需要在空格后面加上 偶数 个引号。

也可以处理转义的引号,例如

key="foo \"quoted text\" bar"

使用这个正则表达式:

 +(?=(?:(?:(?:\\"|[^"])*(?<!\\)"){2})*(?:\\"|[^"])*$)

live demo

【讨论】:

  • 这个处理转义引号吗?
  • @Schwern 答案现在包括一个“逃避证明”正则表达式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多