解析文本、伪标记以转换为用于导航的 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>
我正在尝试找到一种干净的方法来转换这段文本:
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>