在 PHP 中将字符串转换为多维数组

Converting string to multidimensional array in PHP

我将其作为字符串输入。

$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 和其他任何地方,但是我已经花了大约六个小时在这上面,但我仍然被困住了。我已经尝试过爆炸、preg_replace、array_walk_recursive(以及爆炸),从最大的层次结构到更小的层次结构(迄今为止最好的结果),反之亦然,但没有。如何在 PHP 中将字符串转换为多维数组,并通过字符串中的标签设置层次结构?

非常感谢!

$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."
}

所以只需在 trim 尾随空格中添加一些额外的逻辑,就可以了

这个代码

$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]);

将return

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.
)
// 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);