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

我有以下字符串,它是来自我们网络上的投影仪的发现数据包:


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在线测试时,它似乎与所有内容都匹配得很好,除了编号组,但我可以很容易地忽略那些:


匹配 1


SDKClass [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) ""

 }

}

我的正则表达式有什么问题,我该如何解决?我已经尝试了几乎所有表达式组合(我现在几乎是正则表达式大师:\)


收到一只叮咚
浏览 330回答 2
2回答

江户川乱折腾

据我所知,它与您编写的完全一样,并且在 regex101 和 Go 中都同样出色。您观察到的差异仅仅是因为结果呈现方式的不同。让我们仔细看看 regex101 返回的结果。例如,这个:MATCH 1SDKClass&nbsp; &nbsp; [15-29]&nbsp; `VideoProjector`8.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [15-29]&nbsp; `VideoProjector`它基本上说它找到了两个子匹配,其中一个被命名,另一个在索引 8 上。让我们看看 Go:([]string) (len=9 cap=9) {&nbsp; (string) (len=24) "SDKClass=VideoProjector>",&nbsp; (string) "",&nbsp; (string) "",&nbsp; (string) "",&nbsp; (string) "",&nbsp; (string) "",&nbsp; (string) "",&nbsp; (string) (len=14) "VideoProjector",&nbsp; (string) (len=14) "VideoProjector"&nbsp;},它说它找到了两个子匹配,分别是第 7 组和第 8 组。为了获得第 7 组的名称,您应该调用r.SubexpNames(),它将返回SDKClassfor r.SubexpNames()[7]。所以两者都返回相同的结果。

手掌心

所以在 AlexAtNet 的帮助下,我得到了一个答案——足以让我继续前进。这是我的最终代码:r, _ := regexp.Compile("<-([^=]+)=([^>]+)>")match := r.FindAllString(string(msg), -1)result := make(map[string]string)for _, p := range match {&nbsp; &nbsp; split := strings.Split(p, "=")&nbsp; &nbsp; result[split[0]] = split[1]}结果如下:([]string) (len=4 cap=10) {&nbsp;(string) (len=23) "SDKClass=VideoProjector",&nbsp;(string) (len=17) "UUID=B8AC6FDFE1E2",&nbsp;(string) (len=9) "Make=DELL",&nbsp;(string) (len=11) "Model=S300w"&nbsp;(string) (len=14) "Revision=0.2.0"}但我可以简单地Split()通过字符串=获取属性名称和值。我仍在寻找对我的正则表达式和/或代码的改进,这样我就可以了解如何在不需要额外拆分或过多代码的情况下正确地做到这一点。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go