【问题标题】:Converting string to multidimensional array in PHP在PHP中将字符串转换为多维数组
【发布时间】:2015-03-22 05:00:38
【问题描述】:

我将此作为字符串输入。

$str = '[2]Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vulputate cursus nulla, at rhoncus ante egestas vitae. [3]Cras euismod aliquet hendrerit. [3]Integer tortor lorem, suscipit a ante id, faucibus iaculis dolor. Sed aliquet, erat sit amet porta efficitur, eros lorem hendrerit purus, eget pellentesque lacus sapien ut dolor. [3]Donec eget accumsan velit. [4]Vestibulum consectetur enim in nunc fermentum lacinia. Maecenas fermentum rutrum sodales. Quisque vulputate, dolor tempus luctus cursus, massa urna ultrices odio, non dictum sem nulla ac mi. Quisque egestas tellus velit, non elementum lorem consequat id. Proin bibendum feugiat mollis. Sed vel odio neque. [4]Tempo. [2]Phasellus ut mauris purus. Quisque vel tortor erat. [2]Donec eget accumsan velit.';

我正在努力解决这个问题......

array (
[0] => array ( //First [2] and everything below
    [0] => Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vulputate cursus nulla, at rhoncus ante egestas vitae.
    [1] => array ( //[3]s that belong to first [2]
        [0] => Cras euismod aliquet hendrerit. //First [3]
        [1] => Integer tortor lorem, suscipit a ante id, faucibus iaculis dolor. Sed aliquet, erat sit amet porta efficitur, eros lorem hendrerit purus, eget pellentesque lacus sapien ut dolor. //Second [3]
        [2] => array ( //Third [3] and everything below
            [0] => Donec eget accumsan velit.
            [1] => array (
                [0] => Vestibulum consectetur enim in nunc fermentum lacinia. Maecenas fermentum rutrum sodales. Quisque vulputate, dolor tempus luctus cursus, massa urna ultrices odio, non dictum sem nulla ac mi. Quisque egestas tellus velit, non elementum lorem consequat id. Proin bibendum feugiat mollis. Sed vel odio neque.
                [1] => Tempo.
                )
            )
        )
[1] => Phasellus ut mauris purus. Quisque vel tortor erat. //Second [2]
[2] => Donec eget accumsan velit. //Third [2]

)

我已经尝试了我所知道的一切,并且可以找到@php.net 和其他任何地方,但是我已经花了大约六个小时来解决这个问题,但我仍然陷入困境。我尝试过explode、preg_replace、array_walk_recursive(以及explode),从最大的层次结构到更小的层次结构(迄今为止最好的结果),反之亦然,但没有。如何在 PHP 中将字符串转换为多维数组,通过字符串中的标签设置层次结构?

非常感谢!

【问题讨论】:

  • 您需要递归地执行此操作:最初在 [2] 上展开,然后 walk[3] 上拆分生成的数组,在 @987654325 上遍历生成的数组拆分@ 等,直到您在进入下一个级别之前获得任何级别的空白
  • 嗨,马克,感谢您的快速回答!每次我尝试爆炸时,我最终都会将第一个 [3]s 与父 [2] 放在同一数组级别。只有下面有[4][3] 被转移(稍后,通过另一个爆炸)到较低的级别,导致同样的问题,只是在数组中更深。
  • 我确实收到了关于你的答复的通知,马克,但现在似乎已经消失了。 @StackOverflow 出了什么问题?
  • 问题在于第 2 层与子数组中后续层的逻辑不同,因此需要额外检查

标签: php multidimensional-array explode substr


【解决方案1】:
$str = '[2]Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vulputate cursus nulla, at rhoncus ante egestas vitae. [3]Cras euismod aliquet hendrerit. [3]Integer tortor lorem, suscipit a ante id, faucibus iaculis dolor. Sed aliquet, erat sit amet porta efficitur, eros lorem hendrerit purus, eget pellentesque lacus sapien ut dolor. [3]Donec eget accumsan velit. [4]Vestibulum consectetur enim in nunc fermentum lacinia. Maecenas fermentum rutrum sodales. Quisque vulputate, dolor tempus luctus cursus, massa urna ultrices odio, non dictum sem nulla ac mi. Quisque egestas tellus velit, non elementum lorem consequat id. Proin bibendum feugiat mollis. Sed vel odio neque. [4]Tempo. [2]Phasellus ut mauris purus. Quisque vel tortor erat. [2]Donec eget accumsan velit.';

$counter = 2;
function splitLevel($str, $counter) {
    if (strpos($str, '['.$counter.']') === false) {
        return $str;
    }
    $split = array_values(
        array_filter(
            explode('['.$counter.']', $str)
        )
    );

    array_walk(
        $split,
        function(&$value) use ($counter) {
            $value = splitLevel($value, ++$counter);
        }
    );

    if (($counter > 2) && (count($split) > 1)) {
        $first = array_shift($split);
        $split = array($first, $split);
    }
    return $split;
}
$array = splitLevel($str, $counter);

var_dump($array);

给了

array(3) {
  [0]=>
  array(2) {
    [0]=>
    string(117) "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vulputate cursus nulla, at rhoncus ante egestas vitae. "
    [1]=>
    array(3) {
      [0]=>
      string(32) "Cras euismod aliquet hendrerit. "
      [1]=>
      string(179) "Integer tortor lorem, suscipit a ante id, faucibus iaculis dolor. Sed aliquet, erat sit amet porta efficitur, eros lorem hendrerit purus, eget pellentesque lacus sapien ut dolor. "
      [2]=>
      array(2) {
        [0]=>
        string(27) "Donec eget accumsan velit. "
        [1]=>
        array(2) {
          [0]=>
          string(306) "Vestibulum consectetur enim in nunc fermentum lacinia. Maecenas fermentum rutrum sodales. Quisque vulputate, dolor tempus luctus cursus, massa urna ultrices odio, non dictum sem nulla ac mi. Quisque egestas tellus velit, non elementum lorem consequat id. Proin bibendum feugiat mollis. Sed vel odio neque. "
          [1]=>
          string(7) "Tempo. "
        }
      }
    }
  }
  [1]=>
  string(52) "Phasellus ut mauris purus. Quisque vel tortor erat. "
  [2]=>
  string(26) "Donec eget accumsan velit."
}

所以只需添加一些额外的逻辑来修剪尾随空格,你应该会很好

【讨论】:

  • 太完美了,马克!太感谢了。它在我的家庭服务器(PHP5.4.37)上运行起来就像一个魅力。现在我刚刚发现我的公共服务器运行的是 PHP5.2.42,所以我不能运行匿名函数。如何调用 array_walk 并将参数正确传递给命名函数?
  • 你真的应该升级你的公共服务器,PHP 5.2 早在 2011 年就已经停产了,甚至 PHP 5.3 也已经停产了 5 个月
  • 请注意,@axiac 给出的答案与我自己的工作方式几乎相同,他确实展示了如何避免早期版本的 PHP 关闭
  • 我会尝试说服管理员这样做。感谢您的回答和cmets!尽管发生了微小的变化,但它让我找到了解决这个问题的正确道路!
【解决方案2】:

这段代码

$str = '<your_string>';

function stringToArray($str, $delimiter = 2, $isFirst = false) {
    $delimiterStr = "[{$delimiter}]";
    $outArr = array();
    if (strpos($str,$delimiterStr)!==false) {
        $outArr = explode($delimiterStr, $str);         
        $isFirstElement = true;
        $tempArr = array();
        $key = 0;
        foreach ($outArr AS $v) {

            if (!empty($v))
            {
                if ($isFirstElement) {
                    $tempArr[$key] = stringToArray($v, $delimiter+1);
                    $key++;
                } else {
                    $tempArr[$key][] = stringToArray($v, $delimiter+1);
                }                                                       
            }
            $isFirstElement = false;                                
        }
        $outArr = $tempArr;     
    }
    if (!$outArr) {return trim($str);} else {return $outArr;}
}

$elements = stringToArray($str);
print_r($elements[0]);

会回来

Array
(
[0] => Array
    (
        [0] => Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vulputate cursus nulla, at rhoncus ante egestas vitae.
        [1] => Array
            (
                [0] => Cras euismod aliquet hendrerit.
                [1] => Integer tortor lorem, suscipit a ante id, faucibus iaculis dolor. Sed aliquet, erat sit amet porta efficitur, eros lorem hendrerit purus, eget pellentesque lacus sapien ut dolor.
                [2] => Array
                    (
                        [0] => Donec eget accumsan velit.
                        [1] => Array
                            (
                                [0] => Vestibulum consectetur enim in nunc fermentum lacinia. Maecenas fermentum rutrum sodales. Quisque vulputate, dolor tempus luctus cursus, massa urna ultrices odio, non dictum sem nulla ac mi. Quisque egestas tellus velit, non elementum lorem consequat id. Proin bibendum feugiat mollis. Sed vel odio neque.
                                [1] => Tempo.
                            )

                    )

            )

    )

[1] => Phasellus ut mauris purus. Quisque vel tortor erat.
[2] => Donec eget accumsan velit.
)

【讨论】:

    【解决方案3】:
    // The string to parse
    $str = '[2]Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vulputate cursus nulla, at rhoncus ante egestas vitae. [3]Cras euismod aliquet hendrerit. [3]Integer tortor lorem, suscipit a ante id, faucibus iaculis dolor. Sed aliquet, erat sit amet porta efficitur, eros lorem hendrerit purus, eget pellentesque lacus sapien ut dolor. [3]Donec eget accumsan velit. [4]Vestibulum consectetur enim in nunc fermentum lacinia. Maecenas fermentum rutrum sodales. Quisque vulputate, dolor tempus luctus cursus, massa urna ultrices odio, non dictum sem nulla ac mi. Quisque egestas tellus velit, non elementum lorem consequat id. Proin bibendum feugiat mollis. Sed vel odio neque. [4]Tempo. [2]Phasellus ut mauris purus. Quisque vel tortor erat. [2]Donec eget accumsan velit.';
    
    // Parse the string, start with level 2
    $array = analyze($str, 2);
    
    // Ignore the fragment before the first '[2]' (it's empty)
    array_shift($array);
    // Display the list of fragments marked with '[2]` and their offspring
    print_r(current($array));
    
    
    /**
     * Analyze the string $string, search for sections labeled with '[N]'
     * (N = $level).
     * Return an array with two elements: the text before the first '[N]'
     * marker and an array of the fragments that start with '[N]' marker.
     * Each fragment is parsed using the same function.
     *
     * Return the input string ($string) if it does not contain the marker.
     */
    function analyze($string, $level)
    {
        // The marker
        $marker = '['.$level.']';
    
        // If the marker does not exist in the string then this is a leaf
        if (strpos($string, $marker) === FALSE) {
            // Return the input string
            return $string;
        }
    
        // Split by section marker
        $pieces = explode($marker, $string);
    
        // Extract the first fragment; it is returned as is
        $first = array_shift($pieces);
    
        // Analyze the pieces, search for the next level
        return array(
            $first,           // First fragment as is
            array_map(        // Parse the rest using the same function (one level deeper)
                function ($piece) use ($level) {
                    return analyze($piece, $level + 1);
                },
                $pieces
            ),
        );
    }
    

    为了在 5.3 之前的 PHP 版本(引入匿名函数时)上使用它,请将最后一段代码(以 return array( 开头)替换为:

    // Analyze the pieces, search for the next level
    $rest = array();
    foreach ($pieces as $piece) {
        $rest[] = analyze($piece, $level + 1);
    }
    return array($first, $rest);
    

    【讨论】:

      猜你喜欢
      • 2015-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-23
      • 1970-01-01
      • 2019-02-13
      • 2012-11-17
      相关资源
      最近更新 更多