正则表达式提取注释参数

时间:2013-12-11 05:52:57

标签: php regex preg-match-all

我想提取注释中存在的参数

我做到了这一点

$str = "(action=bla,arg=2,test=15,op)";
preg_match_all('/([^\(,]+)=([^,\)]*)/', $str, $m);

$data = array_combine($m[1], $m[2]);
var_dump($data);

这给出了以下输出

array (size=3)
  'action' => string 'bla' (length=3)
  'arg' => string '2' (length=1)
  'test' => string '15' (length=2)

这是忽略op(但我希望它具有null或空值)

但我希望改进这一点,以便它也可以提取这些

  • (action ='val',abc)在这种情况下,单引号内的值将分配给操作
  • (action =“val”,abc)与上述相同,但它也在双引号
  • 之间提取值
  • (action = [123,11,23])现在动作动作将包含数组123,11,23(这也需要提取引用或不引用)

我不想要完整的解决方案(如果你能做到最受欢迎)但我至少需要前两个

修改

(根据与r3mus的讨论编辑) 输出应该像

array (size=3)
  'action' => string 'bla' (length=3)
  'arg' => string '2' (length=1)
  'test' => string '15' (length=2)
  'op' => NULL

3 个答案:

答案 0 :(得分:1)

修改

这最终比一个简单的正则表达式复杂得多。它最终看起来像(第一次通过):

function validate($str)
{
    if (preg_match('/=\[(.*)\]/', $str, $m))
    {
        $newstr = preg_replace("/,/", "+", $m[1]);
        $str = preg_replace("/".$m[1]."/", $newstr, $str);
    }
    preg_match('/\((.*)\)/', $str, $m);
    $array = explode(",", $m[1]);
    $output = array();
    foreach ($array as $value)
    {
        $pair = explode("=", $value);
        if (preg_match('/\[(.*)\]/', $pair[1]))
            $pair[1] = explode("+", $pair[1]);
        $output[$pair[0]] = $pair[1];
    }
    if (!isset($output['op']))
        return $output;
    else
        return false;
}

print_r(validate("(action=[123,11,23],arg=2,test=15)"));

不合适的旧东西:

怎么样:

([^\(,]+)=(\[.*\]|['"]?(\w*)['"]?)

工作示例/沙箱:http://regex101.com/r/bZ8qE6

或者,如果您只需捕​​获[]中的数组:

([^\(,]+)=(\[(.*)\]|['"]?(\w*)['"]?)

答案 1 :(得分:1)

我知道它得到了回答,但你可以做到这一点,我认为这就是你想要的:

$str = '(action=bla,arg=2,test=15,op)';
preg_match_all('/([^=,()]+)(?:=([^,)]+))?/', $str, $m);
$data = array_combine($m[1], $m[2]);
echo '<pre>' . print_r($data, true) . '</pre>';

<强> OUTPUTS

Array
(
    [action] => bla
    [arg] => 2
    [test] => 15
    [op] => 
)

答案 2 :(得分:0)

您可以使用此代码:

<pre><?php
$subject = '(action=bla,arg=2,test=15,op, arg2=[1,2,3],arg3 = "to\\"t,o\\\\", '
         . 'arg4 = \'titi\',arg5=) blah=312';

$pattern = <<<'LOD'
~
(?: \(\s* | \G(?<!^) ) # a parenthesis or contiguous to a precedent match
(?<param> \w+ )
(?: \s* = \s*
     (?|  (?<value> \[ [^]]* ] )                     # array
       | "(?<value> (?> [^"\\]++ | \\{2} | \\. )* )" # double quotes
       | '(?<value> (?> [^'\\]++ | \\{2} | \\. )* )' # single quotes
       |  (?<value> [^\s,)]++ )                      # other value
     )? # the value can be empty
)?      # the parameter can have no value
\s*
(?:
    , \s*                   # a comma
  |                         # OR
    (?= (?<control> \) ) )  # followed by the closing parenthesis
)
~xs
LOD;
preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER);

foreach($matches as $match) {
    printf("<br>%s\t%s", $match['param'], $match['value']);
    if (isset($match['control'])) echo '<br><br>#closing parenthesis#';
}
?></pre>