【问题标题】:Convert multidimensional array string to array将多维数组字符串转换为数组
【发布时间】:2019-09-01 02:20:46
【问题描述】:

PHP 中有一个内置函数或者一些干净的函数可以将多维数组字符串转换为数组吗?

类似字符串:

['text', 'te\'"x2t', "text", "te\"x'#t", true, True, [false, False, 100, +100], -100, + 10, -   20]

每个值可以是字符串(+转义字符)、布尔值、int(+符号)和数组,使其成为一个多维数组。

收件人:

Array
(
    [0] => text
    [1] => te'"x2t
    [2] => text
    [3] => te"x'#t
    [4] => 1
    [5] => 1
    [6] => Array
        (
            [0] => 
            [1] => 
            [2] => 100
            [3] => 100
        )

    [7] => -100
    [8] => 10
    [9] => -20
)

我为此编写了一个正则表达式,它使匹配对这些语句下的字符串有效。 因此,如果字符串不遵循规则,它将不匹配。

(?<_ARRAY>\[\s*(?:(?:(?P>VALUE)|(?P>_ARRAY))\s*,\s*)*(?:(?:(?P>VALUE)|(?P>_ARRAY))\s*)\])

现在我想按原样保存值,不做任何更改。

可以用eval来完成,但据我所知,eval是有风险的,不知道有没有更好的解决方案。

if (preg_match('/(?<_ARRAY>\[\s*(?:(?:(?P>VALUE)|(?P>_ARRAY))\s*,\s*)*(?:(?:(?P>VALUE)|(?P>_ARRAY))\s*)\])/', $array))
    eval("\$array = $array;");

【问题讨论】:

  • @thmsdnnr 我在副本中看不到任何真正有助于 OP 的内容,因为答案都取决于是否有一个有效的数组开头。

标签: php


【解决方案1】:

更新

this 的一些启发下,我想出了这个,这似乎可行。基本上,字符串在引号内不出现的逗号和左右方括号或单/双引号字符串上拆分,每个部分都经过处理以将其转换为有效的 JSON 值。然后将字符串重新组合在一起并使用json_decode转换为数组:

$str = "['text', 'te\\'\"x,2t', \"tex,t\", \"te\\\"x'#t\", true, True, [false, False, 100, +100], -100, + 10, -   20]";
$parts = preg_split('/\s*("(?:\\\\"|[^"])*"|\'(?:\\\\\'|[^\'])*\')\s*|\s*([,\[\]])\s*/', $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
foreach ($parts as &$part) {
    if (preg_match("/^'(.*)'/", $part, $matches)) {
        $part = '"' . str_replace(array('"', "\\'"), array('\\"', "'"), $matches[1]) . '"';
        continue;
    }
    $lpart = strtolower($part);
    if ($lpart == 'true' || $lpart == 'false') {
        $part = $lpart;
        continue;
    }
    if (preg_match('/^\+\s*(\d+)$/', $part, $matches)) {
        $part = $matches[1];
        continue;
    }
    if (preg_match('/^-\s*(\d+)$/', $part, $matches)) {
        $part = '-' . $matches[1];
        continue;
    }
}
$json = implode('', $parts);
var_dump(json_decode($json));

输出:

array(10) {
  [0]=>
  string(4) "text"
  [1]=>
  string(8) "te'"x,2t"
  [2]=>
  string(5) "tex,t"
  [3]=>
  string(7) "te"x'#t"
  [4]=>
  bool(true)
  [5]=>
  bool(true)
  [6]=>
  array(4) {
    [0]=>
    bool(false)
    [1]=>
    bool(false)
    [2]=>
    int(100)
    [3]=>
    int(100)
  }
  [7]=>
  int(-100)
  [8]=>
  int(10)
  [9]=>
  int(-20)
}

Demo on 3v4l.org

原答案

如果将所有单引号都转换为双引号,则字符串是有效的JSON,可以使用json_decode解码:

$str = "['text', 'text', 100, ['text', false], false, ['text', 200], 'text']";
$json = str_replace("'", '"', $str);
print_r(json_decode($json));

输出:

Array
(
    [0] => text
    [1] => text
    [2] => 100
    [3] => Array
        (
            [0] => text
            [1] => 
        )    
    [4] => 
    [5] => Array
        (
            [0] => text
            [1] => 200
        )    
    [6] => text
)

Demo on 3v4l.org

【讨论】:

  • 哦,这就是我尝试时 json_decode 不起作用的原因。但是,我不能使用它,因为某些字符串可以带有转义引号,而其他字符串可以带有双引号。加上额外的代码,就可以搞定,不过不知道有没有更简单的方法呢。
  • @Namixo 您能否发布您正在使用的实际字符串,或者至少是一个显示您正在处理的所有潜在边缘情况的代表性示例?否则,您可能会得到与您的用例无关的简单答案。谢谢。
  • @Namixo 它仍然应该可以将您的字符串转换为有效的 JSON,尽管显然有点复杂。除了eval 或在逗号上非常复杂的拆分(但不在引号或[] 内),我不确定您还有什么其他选择。您可以在您的问题中添加一些其他示例数据吗?
  • @Nick 我编辑了帖子,你认为 eval 是一个很好的解决方案吗?据我所知,eval 是邪恶的 :-) 感谢您的帮助!
  • @Namixo 是否可以在字符串值中使用逗号?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-13
  • 2012-11-17
相关资源
最近更新 更多