可能重复:
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)
不会削减它,因为这些块中也有逗号...
有一种方法可以可靠地爆炸,即使所需的块中有逗号
答案 0 :(得分:4)
有没有办法可靠地爆炸,即使所需的块内有逗号?
默认情况下,PHP不提供这样的功能。但是,在字符串中有一个紧凑的PHP子集,PHP在这里提供了一些工具:PHP tokenizer和PHP 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破解快速代码,但我想你可能会有这个想法。