为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 中的正则表达式命名组无法正确捕获

Golang 中的正则表达式命名组无法正确捕获

Go
收到一只叮咚 2021-10-25 20:31:41
我有以下字符串,它是来自我们网络上的投影仪的发现数据包:AMXB<-SDKClass=VideoProjector><-UUID=ABCDEFG><-Make=DELL><-Model=S300w><-Revision=0.2.0>我正在尝试编写一些将其转换为地图的 Golang 代码,以便我可以调用details["UUID"]并让它返回ABCDEFG。我写了一个看起来像这样的正则表达式:(?:UUID=)(?P<UUID>(.*?))>|(?:Make=)(?P<Make>(.*?))>|(?:Model=)(?P<Model>(.*?))>|(?:SDKClass=)(?P<SDKClass>(.*?))>当我使用regex 101在线测试时,它似乎与所有内容都匹配得很好,除了编号组,但我可以很容易地忽略那些:匹配 1SDKClass [15-29] VideoProjector[15-29] 投影仪第 2 场UUID [37-49] B8AC6FDFE1E2[37-49] B8AC6FDFE1E2第 3 场制造 [57-61] 戴尔[57-61] 戴尔第 4 场型号 [70-75] S300w[70-75] S300w但是当我在 Golang 中尝试时,我得到了不同的结果(注意:这些结果使用 go- spew整理以使其更易于阅读):([][]string) (len=4 cap=10) { ([]string) (len=9 cap=9) {  (string) (len=24) "SDKClass=VideoProjector>",  (string) "",  (string) "",  (string) "",  (string) "",  (string) "",  (string) "",  (string) (len=14) "VideoProjector",  (string) (len=14) "VideoProjector" }, ([]string) (len=9 cap=9) {  (string) (len=18) "UUID=B8AC6FDFE1E2>",  (string) (len=12) "B8AC6FDFE1E2",  (string) (len=12) "B8AC6FDFE1E2",  (string) "",  (string) "",  (string) "",  (string) "",  (string) "",  (string) "" }, ([]string) (len=9 cap=9) {  (string) (len=10) "Make=DELL>",  (string) "",  (string) "",  (string) (len=4) "DELL",  (string) (len=4) "DELL",  (string) "",  (string) "",  (string) "",  (string) "" }, ([]string) (len=9 cap=9) {  (string) (len=12) "Model=S300w>",  (string) "",  (string) "",  (string) "",  (string) "",  (string) (len=5) "S300w",  (string) (len=5) "S300w",  (string) "",  (string) "" }}我的正则表达式有什么问题,我该如何解决?我已经尝试了几乎所有表达式组合(我现在几乎是正则表达式大师:\)
查看完整描述

2 回答

?
江户川乱折腾

TA贡献1851条经验 获得超5个赞

据我所知,它与您编写的完全一样,并且在 regex101 和 Go 中都同样出色。您观察到的差异仅仅是因为结果呈现方式的不同。


让我们仔细看看 regex101 返回的结果。例如,这个:


MATCH 1

SDKClass    [15-29]  `VideoProjector`

8.          [15-29]  `VideoProjector`

它基本上说它找到了两个子匹配,其中一个被命名,另一个在索引 8 上。让我们看看 Go:


([]string) (len=9 cap=9) {

  (string) (len=24) "SDKClass=VideoProjector>",

  (string) "",

  (string) "",

  (string) "",

  (string) "",

  (string) "",

  (string) "",

  (string) (len=14) "VideoProjector",

  (string) (len=14) "VideoProjector"

 },

它说它找到了两个子匹配,分别是第 7 组和第 8 组。为了获得第 7 组的名称,您应该调用r.SubexpNames(),它将返回SDKClassfor r.SubexpNames()[7]。


所以两者都返回相同的结果。


查看完整回答
反对 回复 2021-10-25
?
手掌心

TA贡献1942条经验 获得超3个赞

所以在 AlexAtNet 的帮助下,我得到了一个答案——足以让我继续前进。这是我的最终代码:


r, _ := regexp.Compile("<-([^=]+)=([^>]+)>")


match := r.FindAllString(string(msg), -1)

result := make(map[string]string)


for _, p := range match {

    split := strings.Split(p, "=")

    result[split[0]] = split[1]

}

结果如下:


([]string) (len=4 cap=10) {

 (string) (len=23) "SDKClass=VideoProjector",

 (string) (len=17) "UUID=B8AC6FDFE1E2",

 (string) (len=9) "Make=DELL",

 (string) (len=11) "Model=S300w"

 (string) (len=14) "Revision=0.2.0"

}

但我可以简单地Split()通过字符串=获取属性名称和值。


我仍在寻找对我的正则表达式和/或代码的改进,这样我就可以了解如何在不需要额外拆分或过多代码的情况下正确地做到这一点。


查看完整回答
反对 回复 2021-10-25
  • 2 回答
  • 0 关注
  • 234 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信