2013-02-25 91 views
1

我试图像这样来解析包含空格分隔的密钥=>值对文件,格式:PHP等效Python的shlex.split的

host=db test="test test" blah=123 

通常,该文件是由Python和摄取使用shlex.split解析,但我一直无法找到一个PHP的等价物,我试图用preg_splitstrtok进行逻辑处理的尝试效率不高。

是否有一个PHP等价于Python的shlex.split

+0

据我所知,没有函数会产生你正在寻找的确切行为,但是,这两步应该是微不足道的。您可以使用'preg_match_all'将字符串分解成一个数组,然后遍历数组,将其转换为您需要的格式。 – datasage 2013-02-25 19:24:47

+0

类似于[用于匹配名称值对的正则表达式](http://stackoverflow.com/questions/168171/regular-expression-for-parsing-name-value-pairs),用','替换为'\ s '将允许preg_match_all工作。 – mario 2013-02-25 19:28:27

回答

2

不幸的是,没有内置的PHP函数可以本地处理这样的分隔参数。不过,你可以使用一点正则表达式和一些数组散步来快速创建一个。这只是一个例子,只适用于您提供的字符串类型。任何额外的条件将需要被添加到正则表达式,以确保它正确地匹配模式。在遍历文本文件时,可以轻松调用此函数。

/** 
* Parse a string of settings which are delimited by equal signs and seperated by white 
* space, and where text strings are escaped by double quotes. 
* 
* @param String $string String to parse 
* @return Array   The parsed array of key/values 
*/ 
function parse_options($string){ 
    // init the parsed option container 
    $options = array(); 

    // search for any combination of word=word or word="anything" 
    if(preg_match_all('/(\w+)=(\w+)|(\w+)="(.*)"/', $string, $matches)){ 
     // if we have at least one match, we walk the resulting array (index 0) 
     array_walk_recursive(
      $matches[0], 
      function($item) use (&$options){ 
       // trim out the " and explode at the = 
       list($key, $val) = explode('=', str_replace('"', '', $item)); 
       $options[$key] = $val; 
      } 
     ); 
    } 

    return $options; 
} 

// test it 
$string = 'host=db test="test test" blah=123'; 

if(!($parsed = parse_options($string))){ 
    echo "Failed to parse option string: '$string'\n"; 
} else { 
    print_r($parsed); 
} 
+0

这是一个非常糟糕的答案,相当于'shlex.split'。因为它甚至不能把'a“b c”'处理成'[“a”,“b c”]'。 – Vallentin 2016-03-26 13:46:49