解析文本、伪标记以转换为用于导航的 UL 列表 php

Parsing text, pseudo markup to convert to UL list for navigation php

我正在尝试找到一种干净的方法来转换这段文本:

1 |一级 | /url/segments/here
1 |一级 | /url/segments/here
2 |二级 | /url/segments/here
2 |二级 | /url/segments/here
3 |三级 | /url/segments/here
2 |二级 | /url/segments/here
1 |一级 | /url/segments/here
1 |一级 | /url/segments/here
1 |一级 | /url/segments/here

变成这样的结构:

  <ul>
   <li><a href="#" title="">Level One</a></li>
   <li><a href="#" title="">Level One</a>
      <ul>
         <li><a href="#" title="">Level Two</a></li>
         <li><a href="#" title="">Level Two</a>
            <ul>
               <li><a href="#" title="">Level Three</a></li>
            </ul>
         </li>
         <li><a href="#" title="">Level Two</a></li>
      </ul>
   </li>
   <li><a href="#" title="">Level One</a></li>
   <li><a href="#" title="">Level One</a></li>
   <li><a href="#" title="">Level One</a></li>
  </ul>

我曾尝试使用 explode() 并弄乱它创建的数组,但在进入第 2 级和第 3 级导航时,我不知道何时嵌套 UL。

下午 4 点更新 几乎可以正常工作,只需要弄清楚如何将 UL 正确嵌套在 LI 中,因为就 html 标记而言,目前它还不是 100% 正确。

<?php

$navi_text = "1 | Level One | /url/segments/here  
1 | Level One | /url/segments/here  
2 | Level Two | /url/segments/here  
2 | Level Two | /url/segments/here  
3 | Level Three | /url/segments/here  
2 | Level Two | /url/segments/here  
1 | Level One | /url/segments/here  
1 | Level One | /url/segments/here  
1 | Level One | /url/segments/here";



$each_row = explode("\n", $navi_text);


$nav_position = '1';

echo "<ul>";


foreach ($each_row as $rowKEY => $rowVAL) 
    {

        $piped_items = explode(" | ", $rowVAL);


        if($piped_items[0] == "1" && $nav_position == "1")
            {
                echo '<li><a href="">' .  $piped_items[1] . '</a></li>';
            }
        if($piped_items[0] == "2" && $nav_position == "1")
            {
                echo '<ul><li><a href="">' .  $piped_items[1] . '</a></li>';
                $nav_position = "2";
            }
        if($piped_items[0] == "2" && $nav_position == "2")
            {
                echo '<li><a href="">' .  $piped_items[1] . '</a></li>';
            }
        if($piped_items[0] == "3" && $nav_position == "2")
            {
                echo '<ul><li><a href="">' .  $piped_items[1] . '</a></li>';
                $nav_position = "3";
            }
        if($piped_items[0] == "3" && $nav_position == "3")
            {
                echo '<li><a href="">' .  $piped_items[1] . '</a></li>';
            }
        if($piped_items[0] == "2" && $nav_position == "3")
            {
                echo '</ul><li><a href="">' .  $piped_items[1] . '</a></li>';
                $nav_position = "2";
            }
        if($piped_items[0] == "1" && $nav_position == "2")
            {
                echo '</ul><li><a href="">' .  $piped_items[1] . '</a></li>';
                $nav_position = "1";
            }

    }


echo "</ul>";

?>

基本情况:

<?php

$nav_string = "1 | Level One | /url/segments/here  
1 | Level One | /url/segments/here  
2 | Level Two | /url/segments/here  
2 | Level Two | /url/segments/here  
3 | Level Three | /url/segments/here  
2 | Level Two | /url/segments/here  
1 | Level One | /url/segments/here  
1 | Level One | /url/segments/here  
1 | Level One | /url/segments/here";

$nav_array = explode(PHP_EOL, $nav_string);
$nav_stack = array();

$first_nav = array_shift($nav_array);
$first_nav_item = explode("|", $first_nav);
$prev = 1;

echo '<ul><li><a href="#" title="">'.$first_nav_item[1]."</a>";     
$nav_stack[] = '</ul>';
$nav_stack[] = '</li>';

foreach($nav_array as $ind => $nav_item){

    $nav_items = explode("|", $nav_item);

    if($nav_items[0] == $prev){ 
        echo array_pop($nav_stack);
        $nav_stack[] = '</li>';
    } else if($nav_items[0] > $prev){       
        echo '<ul>';    
        $nav_stack[] = '</ul>';
        $nav_stack[] = '</li>';
    } else{
        echo array_pop($nav_stack);
        echo array_pop($nav_stack);
        echo '</li>';
    }

    echo '<li><a href="#" title="">'.$nav_items[1]."</a>";          
    $prev = $nav_items[0];

}

$nav_stack = array_reverse($nav_stack);
foreach($nav_stack as $stack_item){
    echo $stack_item;
}

?>

将生成这个:

<ul>
    <li><a href="#" title=""> Level One </a></li>
    <li><a href="#" title=""> Level One </a>
        <ul>
            <li><a href="#" title=""> Level Two </a></li>
            <li><a href="#" title=""> Level Two </a>
                <ul>
                    <li><a href="#" title=""> Level Three </a></li>
                </ul>
            </li>
            <li><a href="#" title=""> Level Two </a></li>
        </ul>
    </li>
    <li><a href="#" title=""> Level One </a></li>
    <li><a href="#" title=""> Level One </a></li>
    <li><a href="#" title=""> Level One </a></li>
</ul>

现在,如果您的 string/description 导航菜单在第三级结束,而不是信任浏览器的结束标记:堆栈会处理它们。对于以下

$nav_string = "1 | Level One | /url/segments/here  
1 | Level One | /url/segments/here  
2 | Level Two | /url/segments/here  
2 | Level Two | /url/segments/here  
3 | Level Three | /url/segments/here";

脚本将输出:

<ul>
    <li><a href="#" title=""> Level One </a></li>
    <li><a href="#" title=""> Level One </a>
        <ul>
            <li><a href="#" title=""> Level Two </a></li>
            <li><a href="#" title=""> Level Two </a>
                <ul>
                    <li><a href="#" title=""> Level Three </a></li>
                </ul>
            </li>
        </ul>
    </li>   
</ul>

这应该适合你:

首先简单地按每一行 explode() 你的数组,然后用 array_map() 遍历每个元素,在那里你再次将每一行分成 |preg_split()

在此之后,您只需遍历每一行,并根据需要关闭和打开标签的级别:

<?php

    $navi_text = "1 | Level One | /url/segments/here  
1 | Level One | /url/segments/here  
2 | Level Two | /url/segments/here  
2 | Level Two | /url/segments/here  
3 | Level Three | /url/segments/here  
2 | Level Two | /url/segments/here  
1 | Level One | /url/segments/here  
1 | Level One | /url/segments/here  
1 | Level One | /url/segments/here";


    $lines = explode(PHP_EOL, $navi_text);
    $lines = array_map(function($v){
        return preg_split("/(\s*\|\s*)/", $v);
    }, $lines);

    $level = 0;

    foreach($lines as $k => $line) {

        if($line[0] > $level)
            echo "<ul>";
        elseif($line[0] > $level)
            echo "</ul>";

        echo "<li><a href='#' title=''>" . $line[1] . "</a>";

        if(isset($lines[($k+1)]) && $line[0] >= $lines[($k+1)][0])
            echo "</li>";
        if(isset($lines[($k+1)]) && $line[0] > $lines[($k+1)][0])
            echo "</ul></li>";
        if(!isset($lines[($k+1)]))
            echo "</li></ul>";

        $level = $line[0];

    }

?>

输出:

<ul>
    <li><a href='#' title=''>Level One</a></li>
    <li><a href='#' title=''>Level One</a>
        <ul>
            <li><a href='#' title=''>Level Two</a></li>
            <li><a href='#' title=''>Level Two</a>
                <ul>
                    <li><a href='#' title=''>Level Three</a></li>
                </ul>
            </li>
            <li><a href='#' title=''>Level Two</a></li>
        </ul>
    </li>
    <li><a href='#' title=''>Level One</a></li>
    <li><a href='#' title=''>Level One</a></li>
    <li><a href='#' title=''>Level One</a></li>
</ul>