我有以下字符串,它是我们网络上投影仪的发现数据包:
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在线测试时,除了编号组外,它似乎匹配所有内容,但我很容易忽略这些:
MATCH 1
SDKClass [15-29] VideoProjector
- [15-29] VideoProjector
醇>
MATCH 2
UUID [37-49] B8AC6FDFE1E2
- [37-49] B8AC6FDFE1E2
醇>
MATCH 3
制作[57-61]戴尔
- [57-61]戴尔
醇>
MATCH 4
型号[70-75] S300w
- [70-75] S300w
醇>
但是当我在Golang中尝试时,我得到different results(注意:这些结果使用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) ""
}
}
我的正则表达式有什么问题,我该如何解决?我已经尝试了几乎所有表达式的组合(我现在几乎是一个正则表达式大师:\)
答案 0 :(得分:0)
据我所知,它的工作原理与你编写的完全一样,同样适用于regex101和Go。您观察到的差异仅仅是因为结果的呈现方式不同。
让我们仔细看看regex101返回的结果。例如,这一个:
Router::scope('/', function (\Cake\Routing\RouteBuilder $routes) {
// ...
$routes->connect('/users', ['controller' => 'Users', 'action' => 'index']);
$routes->connect('/users/:action/*', ['controller' => 'Users']);
$routes->connect('/foos', ['controller' => 'Foos', 'action' => 'index']);
$routes->connect('/foos/:action/*', ['controller' => 'Users']);
// and so on...
});
它基本上说它找到了两个子匹配,其中一个是命名的,另一个是索引8.让我们看一下Go:
MATCH 1
SDKClass [15-29] `VideoProjector`
8. [15-29] `VideoProjector`
它说它找到了第7组和第8组的两个子匹配。要获取组7的名称,您应该调用([]string) (len=9 cap=9) {
(string) (len=24) "SDKClass=VideoProjector>",
(string) "",
(string) "",
(string) "",
(string) "",
(string) "",
(string) "",
(string) (len=14) "VideoProjector",
(string) (len=14) "VideoProjector"
},
,r.SubexpNames()
将返回SDKClass
r.SubexpNames()[7]
所以两者都返回相同的结果。
答案 1 :(得分:0)
所以在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()
简单地=
字符串,并获取属性名称和值。
我仍然在寻找对我的正则表达式和/或代码的改进,这样我就可以看到如何正确执行它而无需额外的拆分或过多的代码。