Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 从命令行将字符串解析为数组输出_Php_Regex_Bash_Symfony_Docker - Fatal编程技术网

Php 从命令行将字符串解析为数组输出

Php 从命令行将字符串解析为数组输出,php,regex,bash,symfony,docker,Php,Regex,Bash,Symfony,Docker,我正在进行一个新的Symfony 2项目,该项目将是Docker容器的面板管理 在这个项目中,我使用exec()PHP函数执行一些命令 我正在尝试分析以下命令的输出: docker create tutum/lamp:latest --name test 2>&1 当命令成功时,我将获得一个字符串形式的容器ID,该字符串很好使用,但是当出现问题时,它就不一样了。结果是一个带有var=“data”语法的字符串,我想对其进行解析以获得一个数组 命令输出: time="2015-06-

我正在进行一个新的Symfony 2项目,该项目将是Docker容器的面板管理

在这个项目中,我使用
exec()
PHP函数执行一些命令

我正在尝试分析以下命令的输出:

docker create tutum/lamp:latest --name test 2>&1
当命令成功时,我将获得一个字符串形式的容器ID,该字符串很好使用,但是当出现问题时,它就不一样了。结果是一个带有var=“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" ...);
我知道我必须进行正则表达式解析。过了一会儿(我和regex不是真正的好朋友),我得到了这个regex(测试):

我使用了preg_分割函数,我不确定它是否是好的

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 (\\\\").
其他一些注意事项:

  • preg_split
    使用正则表达式匹配应拆分字符串的标记。在这种情况下,这不是你想要的;您希望返回字符串中与正则表达式匹配的部分。为此,您应该使用
    preg\u match
    (或者,如果像这里一样,您希望模式匹配多次),
    preg\u match\u all
  • 还考虑<代码> PrggSeTySyOrgs< /Cult>标志>代码> PrggMatMatyLAL。此标志导致
    $matches
    结果为输出消息中的每个标签包含一行,这使得数据结构易于处理。试着看看如果你忽略它会发生什么 这是因为将字符串一直消耗到最后一个
    。将其设为惰性,将这样做:

    if(preg_match_all('/(\w+)="(.*?)(?<!\\\)"/s', $str, $out))
      print_r(array_combine($out[1], $out[2]));
    

    if(preg\u match\u all('/(\w+)=“(.*)?)如果你只是var\u dump($output)会发生什么?非常感谢你的帮助。如果我理解得很好:\\\\\”只用于解析\“对吗?因此,例如,如果我想逃避,我必须将\\\\n?放在乐意帮助的位置;是的,否则模式将在第一个引号处停止匹配(逃脱与否)。
    
    if(preg_match_all('/(\w+)="(.*?)(?<!\\\)"/s', $str, $out))
      print_r(array_combine($out[1], $out[2]));