将列表缩进到多维数组

  • 本文关键字:数组 列表 缩进 php
  • 更新时间 :
  • 英文 :


我很惊讶没有在SO(或互联网上的其他地方)上找到答案。它涉及一个嵌套的缩进列表,我想根据缩进级别将其转换为多维数组。

举个例子,这里有一些示例输入:

Home
Products
    Product 1
        Product 1 Images
    Product 2
        Product 2 Images
    Where to Buy
About Us
    Meet the Team
    Careers
Contact Us

理想情况下,我想将其输入一些(递归?)函数,并获得以下输出:

array(
    'Home' => array(),
    'Products' => array(
        'Product 1' => array(
            'Product 1 Images' => array(),
        ),
        'Product 2' => array(
            'Product 2 Images' => array(),
        ),
        'Where to Buy' => array(),
    ),
    'About Us' => array(
        'Meet the Team' => array(),
        'Careers' => array(),
    ),
    'Contact Us' => array(),
);

我对执行这样一项任务所需的逻辑感到困惑,所以任何帮助都将不胜感激。

由于还不清楚您是试图从某个给定的结构(html-dom)中读取,还是从给定的字符串中读取纯文本,我认为这是您试图解析的字符串。如果是,请尝试:

<?php
$list =
'Home
Products
    Product 1
        Product 1 Images
    Product 2
        Product 2 Images
    Where to Buy
About Us
    Meet the Team
    Careers
Contact Us';
function helper($list, $indentation = '    ') {
  $result = array();
  $path = array();
  foreach (explode("n", $list) as $line) {
    // get depth and label
    $depth = 0;
    while (substr($line, 0, strlen($indentation)) === $indentation) {
      $depth += 1;
      $line = substr($line, strlen($indentation));
    }
    // truncate path if needed
    while ($depth < sizeof($path)) {
      array_pop($path);
    }
    // keep label (at depth)
    $path[$depth] = $line;
    // traverse path and add label to result
    $parent =& $result;
    foreach ($path as $depth => $key) {
      if (!isset($parent[$key])) {
        $parent[$line] = array();
        break;
      }
      $parent =& $parent[$key];
    }
  }
  // return
  return $result;
}
print_r(helper($list));

演示:http://codepad.org/zgfHvkBV

我不打算编写递归函数,但为了给您指明一个有用的方向,请查看PHP的substra_count函数。基于此,您可以计算每行前面的选项卡数量,并将其与前一行中的选项卡数量进行比较,以确定它是否是子选项卡、同级选项卡等。

我是唯一一个拥有美丽心灵的人吗?

输入数组几乎是一样的!,行的结尾只有三种可能的方式:左括号、全括号或右括号。

$L = 4;//estimate depth level
function tabbed_text_to_array ($raw, $L) {
        $raw = preg_replace("/^(\t*)([^\t\n]*)\n?/m" ,  "t$1'$2' => array(n" , $raw );
    for( ; $L > 0 ; $L-- ) {
        for( $i=0; $i<3 ;$i++ ) {
            $preL = $L-1;
            $s = array( "^(\t{{$L}})([^\t\),]*)(?=\n\t{{$L}}')", "^(\t{{$L}})([^\t\),]*)(?=\n(\t{0,{$preL}})')", "^(\t{{$L}})(\),)(?=\n(\t{{$preL}})[^t])" );
            $r = array(    "$1$2),"   ,     "$1$2)n" . str_repeat("t",$preL) . "),"    ,    "$1),n$3),"    );
            $raw = preg_replace( "/$s[$i]/m" , $r[$i], $raw );
        }
    }
    return "array(n". $raw. ")n);";   
}

此函数生成一个带有文字数组的字符串。然后你就评估它。它并不像看上去那么糟糕。双反斜杠使阅读更加困难,但它很简单。

与细胞复制一样,它首先在一个过程中添加最常见的东西:引号、逗号和大括号,然后在两个过程中再添加较小的细节。对于您指定的每个级别,所有这些都运行一次(您可能会浪费代码来找出最深的级别来开始处理,但猜测就足够了。)

请参阅工作演示/工具,将制表符缩进的文本转换为数组

或者访问一个php fiddle来处理所有的通行证,这样您就可以对此进行扩展。

有一个关于PHP脚本的类可以满足您的需要。你可以在这里找到它:阵列列出

它采用一个多维数组并创建HTML。

更新

事实上,恰恰相反。为此,最好使用DOMDocument对象并将HTML加载到对象表示中。

http://php.net/manual/en/domdocument.loadhtml.php

最新更新