可靠地将包含PHP数组信息的字符串转换为数组

时间:2011-10-24 09:08:51

标签: php arrays string multidimensional-array

  

可能重复:
  Simulate php array language construct or parse with regexp?

假设我有字符串

$str = "array(1,3,4),array(array(4,5,6)),'this is a comma , inside a string',array('asdf' => 'lalal')";

我尝试用逗号将其分解为一个数组,以便得到所需的最终结果

$explode[0] =  array(1,3,4);
$explode[1] = array(array(4,5,6));
$explode[2] = 'this is a comma , inside a string';
$explode[3] = array('asdf' => 'lalal');

简单地调用explode(',',$str)不会削减它,因为这些块中也有逗号...

有一种方法可以可靠地爆炸,即使所需的块中有逗号

2 个答案:

答案 0 :(得分:4)

  

有没有办法可靠地爆炸,即使所需的块内有逗号?

默认情况下,PHP不提供这样的功能。但是,在字符串中有一个紧凑的PHP子集,PHP在这里提供了一些工具:PHP tokenizerPHP parser

因此,您的字符串规范可以创建一个帮助函数,该函数根据允许的令牌验证输入,然后解析它:

$str = "array(1,3,4),array(array(4,5,6)),'this is a comma , inside a string', array('asdf' => 'lalal')";

function explode_string($str)
{
    $result = NULL;

    // validate string
    $isValid = FALSE;
    $tokens = token_get_all(sprintf('<?php %s', $str));
    array_shift($tokens);
    $valid = array(305, 315, 358, 360, 371, '(', ')', ',');
    foreach($tokens as $token)
    {
        list($index) = (array) $token;
        if (!in_array($index, $valid))
        {
            $isValid = FALSE;
            break;
        }
    }
    if (!$isValid)
        throw new InvalidArgumentException('Invalid string.');

    // parse string
    $return = eval(sprintf('return array(%s);', $str));

    return $return;
}

echo $str, "\n";

$result = explode_string($str);

var_dump($result);

使用的令牌是:

T_LNUMBER (305)
T_CONSTANT_ENCAPSED_STRING (315)
T_DOUBLE_ARROW (358)
T_ARRAY (360)
T_WHITESPACE (371)

使用token name可以将令牌索引号设为token_name

给你(Demo):

Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 3
            [2] => 4
        )

    [1] => Array
        (
            [0] => Array
                (
                    [0] => 4
                    [1] => 5
                    [2] => 6
                )

        )

    [2] => this is a comma , inside a string
    [3] => Array
        (
            [asdf] => lalal
        )

)

答案 1 :(得分:0)

您可以编写一个简单的解析器:

function explode_str_arr($str) {
    $str.=',';
    $escape_char = '';
    $str_len = strlen($str);
    $cur_value = '';
    $return_arr = array();
    $cur_bracket_level = 0;
    for ($i = 0; $i < $str_len; $i++) {
        if ($escape_char) {
            if ($str[$i] === $escape_char) {
                $escape_char = '';
            }
            $cur_value.=$str[$i];
            continue;
        }

        switch ($str[$i]) {
            case '\'':
            case '"':
                $escape_char = $str[$i];
                break;
            case '(':
                $cur_bracket_level++;
                break;
            case ')':
                $cur_bracket_level--;
                break;
            case ',':
                if (!$cur_bracket_level) {
                    $return_arr[] = $cur_value;
                    $cur_value = '';
                    continue 2;
                }
        }
        $cur_value.=$str[$i];
    }
    return $return_arr;
}

这是一个丑陋的unicode破解快速代码,但我想你可能会有这个想法。