【问题标题】:How to explode string into multi-leveled array?如何将字符串分解为多级数组?
【发布时间】:2011-10-29 12:11:27
【问题描述】:

我想知道是否可以做这样的事情。

我有以下字符串:

Parent1@MiddleA%Child|Child|Child|MiddleB%Child|Child|Child|Parent2@MiddleA%|Child

我想把它分解成类似的东西:

-Parent1
---MiddleA
------Child
------Child
------Child
---MiddleB
------Child
------Child
------Child
-Parent2
---MiddleA
------Child

我不明白如何分解它然后再次分解它以创建像上面这样的输出。

这个想法是每个父母都将被标识为尾随@,该父母的每个孩子都有一个尾随%,该孩子的每个孩子都将有一个尾随|

【问题讨论】:

  • 是否有理由使用“你自己的”(非)序列化方法而不是 PHP “序列化”和“反序列化”? (或 JSON,就此而言)
  • 您也许可以自定义 JSON 解析器...
  • 我什至不知道 php 提供什么或 json 是什么。我得做一些搜索。

标签: php arrays split explode multi-level


【解决方案1】:

您在问题中作为输入提供的数据:

Parent1@MiddleA%Child|Child|Child|MiddleB%Child|Child|Child|Parent2@MiddleA%|Child

不太适合产生您要求的输出。它的结尾甚至在语法上不正确,特别是 MiddleA%|Child 中的分隔符。

对此,您可以使用preg_split 轻松完成:

$str = 'Parent1@MiddleA%Child|Child|Child|MiddleB%Child|Child|Child|Parent2@MiddleA%Child|';

$elements = preg_split('~([^@%|]+?[@%|])~', $str, 0, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

$types = '@%|';
foreach($elements as $element)
{
    $label = substr($element, 0, -1);
    $type = substr($element, -1);
    $indentValue = strpos($types, $type);
    if (FALSE === $indentValue) throw new Exception('Invalid string given.');
    $indent = str_repeat('-', $indentValue * 2 + 1);
    printf("%s %s\n", $indent, $label);
}

如果您没有有效格式的输入字符串,您需要先修复它,例如使用适当的解析器,或者您需要对 foreach 循环中的虚假案例做出反应。

编辑:这是一个修改后的示例,它将字符串转换为树状结构,因此您可以使用嵌套的foreach 循环输出它:

$str = 'Parent1@MiddleA%Child|Child|Child|MiddleB%Child|Child|Child|Parent2@MiddleA%Child|';

$types = '@%|';
$pattern = sprintf('~([^%1$s]+?[%1$s])~', $types);
$elements = preg_split($pattern, $str, 0, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

$tree = array();
foreach($elements as $element)
{
    $label = substr($element, 0, -1);
    $type = substr($element, -1);
    $indentValue = strpos($types, $type);
    if (FALSE === $indentValue) throw new Exception('Invalid string given.');

    $add =& $tree;
    for($i = $indentValue; $i--;)
    {
        $index = max(0, count($add)-1);
        $add =& $add[$index][1];
    }
    $add[] = array($label, array());
    unset($add);
}

foreach($tree as $level1)
{
    echo '<div>', $level1[0], "\n";
    foreach($level1[1] as $level2)
    {
        echo '  <h3>', $level2[0], '</h3>', "\n";
        foreach($level2[1] as $level3)
        {
            echo '    <span>', $level3[0],'</span>', "\n";
        }
    }
    echo '</div>', "\n";
}

(Demo) - 希望这会有所帮助。

【讨论】:

  • 对不起。我没看到这个。我不知道如何将其从缩进更改为说如果它的级别 1 执行此样式,如果级别 2 执行其他 html。你明白我的意思吗?
  • 等等,我想我可能有它。 BRB。也谢谢你。
  • @JackSmith:检查$indentValue,1 级为 0,2 级为 1,依此类推。如果是FALSE,则发生错误。
  • 我想不通。我试图得到它,以便有一个 $start $value $end,其中 $value 是 $label,$start 和 $end 是封闭的 html。
  • 你想输出什么类型的HTML? &lt;ul&gt;&lt;li&gt;&lt;ul&gt;... 类型的列表?你需要告诉你的问题,否则它是不知道的。我的问题中的输出是您在问题中给出的您想要做什么,如果您希望我在答案中分享更多信息,您需要在您的问题中分享更多信息。
【解决方案2】:

我想没有办法自动将其分解为多维数组,因此您必须编写特定的算法来完成这项工作。 字符串中有一个逻辑序列,因此可以轻松转换。以“@”开始,每个元素以“A%”开始,然后以“|”开始。

【讨论】:

    【解决方案3】:
    <?php
    $string = "Parent1@MiddleA%Child|Child|Child|MiddleB%Child|Child|Child|Parent2@MiddleA%|Child";
    
    $explode1 = explode ("@",$string);
    
    foreach ($explode1 as $str)
    {
    
      $explode2 = explode("|", $str);
    
      foreach ($explode2 as $str2)
      {
        $explode3 = explode ("%", $str2);
    
            foreach($explode3 as $str3)
            {
            echo ($str3 != "") ? $str3 . "<br/>" : "";
            }
      }
    
    }
    ?>
    

    将输出:

    Parent1
    MiddleA
    Child
    Child
    Child
    MiddleB
    Child
    Child
    Child
    Parent2
    MiddleA
    Child
    

    【讨论】:

    • 谢谢!这就说得通了。我从来没有学过 foreach 函数……我怎么没想到?!
    • 这看起来像一个平面列表,我想这真的适合 OP 的要求。
    • 这是真的,如果 OP 希望我这样做,我可以拆分它吗?我的印象是他只是想知道如何爆炸()字符串的要点......
    • 嗯,是的,我试图弄清楚如何设置每个级别的样式。我现在正在试验,但我不熟悉该功能。我只是在看 tizag,但这对我来说没有多大意义。
    • 你的初始字符串有灵活性吗?你想创造什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多