将字符串解析为从命令行输出的数组
·
问题:将字符串解析为从命令行输出的数组
我正在开发一个新的 Symfony 2 项目,该项目将成为 Docker 容器的面板管理。
在这个项目中,我正在使用exec()PHP 函数执行一些命令。
我正在尝试解析以下命令的输出:
docker create tutum/lamp:latest --name test 2>&1
当命令成功时,我会在一个很好且易于使用的字符串中获取容器 ID,但是当出现问题时,它就不一样了。结果是一个带有 varu003d"data" 语法的字符串,我想解析它以获得一个数组。
命令输出:
time="2015-06-21T11:33:26+02:00" level="fatal" msg="Error response from daemon: Conflict. The name \"test\" is already in use by container XXXXXXXX. You have to delete (or rename) that container to be able to reuse that name."
我希望有这样的东西:
Array( time => "2015-06-21T11:33:26+02:00", level => "fatal" ...);
我知道我必须进行正则表达式解析。过了一会儿(正则表达式和我不是真正的好朋友)我得到了这个正则表达式(在https://regex101.com/上测试):
/([a-zA-Z]+)="((.*)*)"/
我使用了 preg_split 函数,我不确定它是否好用。
preg_split('/([a-zA-Z]+)="((.*)*)"/', $output)
结果是:
array(2) { [0]=> string(0) "" [1]=> string(0) "" }
你有什么建议可以帮助我吗?非常感谢您的帮助。
解答
TL;DR: 这应该有效:
preg_match_all(',([a-z]+)="((?:[^"]|\\\\")*[^\\\\])",', $a, $matches, PREG_SET_ORDER);
var_dump($matches);
最后的var_dump打印出如下数据结构,应该很容易处理:
array(3) {
[0] => array(3) {
[0] => string(32) "time="2015-06-21T11:33:26+02:00""
[1] => string(4) "time"
[2] => string(25) "2015-06-21T11:33:26+02:00"
}
[1] => array(3) {
[0] => string(13) "level="fatal""
[1] => string(5) "level"
[2] => string(5) "fatal"
}
[2] => array(3) {
[0] => string(179) "msg="Error response from daemon: Conflict. The name \\"test\\" is already in use by container XXXXXXXX. You have to delete (or rename) that container to be able to reuse that name.""
[1] => string(3) "msg"
[2] => string(173) "Error response from daemon: Conflict. The name \\"test\\" is already in use by container XXXXXXXX. You have to delete (or rename) that container to be able to reuse that name."
}
}
为什么这样有效
正则表达式解释:
([a-z]+) # Match the label ("time", "level" or "msg")
= # Self-explanatory
"((?:[^"]|\\\\")*[^\\\\])" # This is the tricky part:
# Match the quoted string; this is a sequence
# of (a) non-quote characters ([^"]) or
# (b) escaped quote characters (\\\\").
其他一些注意事项:
1.preg_split使用正则表达式来匹配应该分割字符串的token。在这种情况下,这不是您想要的;你想返回被正则表达式_匹配_的字符串部分。为此,您应该使用preg_match(或者,如果像这里一样,您希望一个模式匹配多次),preg_match_all。
- 还要考虑
preg_match_all的PREG_SET_ORDER标志。此标志使$matches结果包含来自输出消息的每个标签的一行,这使得数据结构易于处理。试着看看如果你把它排除在外会发生什么。
更多推荐



所有评论(0)