可靠地将包含PHP数组信息的字符串转换为数组
可能重复:可靠地将包含PHP数组信息的字符串转换为数组,php,arrays,string,multidimensional-array,Php,Arrays,String,Multidimensional Array,可能重复: 假设我有绳子 $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 , i
假设我有绳子
$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)
并不能解决这个问题,因为这些块中也有逗号
是否有一种方法可以可靠地分解此数据,即使所需的数据块中有逗号您可以编写一个简单的解析器:
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;
}
函数explode\u str\u arr($str){
$str.=',';
$escape_char='';
$str_len=strlen($str);
$cur_值=“”;
$return_arr=array();
$cur_bracket_level=0;
对于($i=0;$i<$str_len;$i++){
if($escape\u char){
如果($str[$i]==$escape\u char){
$escape_char='';
}
$cur_值=$str[$i];
继续;
}
交换机($str[$i]){
案例'\'':
案例'':
$escape_char=$str[$i];
打破
格“(”:
$cur_方括号_level++;
打破
案例“)”:
$cur_括号_级别--;
打破
案例',':
如果(!$cur\u括号\u级别){
$return\u arr[]=$cur\u值;
$cur_值=“”;
继续2;
}
}
$cur_值=$str[$i];
}
return$return\u arr;
}
这是一个丑陋的unicode破译快速代码,但我想你可能会明白这一点
即使在所需的块中有逗号,是否有方法可靠地分解它
PHP在默认情况下不提供这样的函数,但是在字符串中有一个紧凑的PHP子集,PHP在这里提供了一些工具:a和a
因此,您的字符串规范可以创建一个助手函数,该函数根据允许的标记验证输入,然后对其进行解析:
$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在以后更容易解析。它是由一个非常复杂但至关重要的第三方函数生成的…如果您能告诉我如何将字符串格式自动转换为json格式,我也会注意到这个问题是由您不明确的分隔符引起的。您能更改将最外面的分隔符转换为除“,”以外的另一个值?这将是最简单的解决方案。另一个可以是正则表达式,但根据字符串的可能值,此正则表达式可能很难创建。代码是否可信?如果是,
print\r(eval(sprintf('return array(%s);“,$str)));
就可以了。不过,要注意所有的eval问题。@Yoshi:。你建议的解析器不完整,它不处理数组中的数组(我看到的最大的概念缺陷),也不处理=>
@hakre:是的,很好的例子,顺便说一句,令牌很好吃:)。但是我们中的一个人误解了这个问题(很可能是我):我想OP不是问如何创建数组等,我看到的唯一问题是如何修复simple explode()处理转义字符串。可能我是瞎子)不,这确实是一个好的观点。我的解析概念可能太复杂了,我对你的答案有点期待。因为如果可以跳过阻止分解的逗号,这已经是工作的一半了。+1-不过,对于文档,我会使用或至少注意要做什么使用了KEN.。@Yoshi:编辑并添加了一个正在使用的令牌列表。只需看看这里的问题非常接近:哪个有类似的答案:
T_LNUMBER (305)
T_CONSTANT_ENCAPSED_STRING (315)
T_DOUBLE_ARROW (358)
T_ARRAY (360)
T_WHITESPACE (371)
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
)
)