首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用文本样式创建带有子列表的列表

使用文本样式创建带有子列表的列表
EN

Stack Overflow用户
提问于 2013-10-15 17:43:33
回答 1查看 135关注 0票数 2

我试图使标记格式化有序列表,下面是标记样式:

代码语言:javascript
复制
$strings = "1. dog
1. cat
1. fish
 1. horse
 1. monkey
1. pig
";

该列表中的horsemonkey应该是子列表的一部分,因为它们在数字之前有一个空格。下面是我使用的代码:

代码语言:javascript
复制
function blq($match){
    $str = preg_replace("/^1\. (.+?)$/m", "<li>$1</li>", $match[0]);
    $str = preg_replace_callback("/(?:^1\. .+(\n|$))+/m", 'blq', $str);
    return "<ol>$str</ol>";
}

$string = preg_replace_callback("/(?:^ ?1\. .+(\n|$))+/m", 'blq', $strings);

echo $string;

该代码正在创建以下输出:

代码语言:javascript
复制
<ol><li>dog
</li>
<li>cat
</li>
<li>fish
</li>
 1. horse
 1. monkey
<li>pig
</li>
</ol>

horsemonkey不是作为子列表创建的,而是被忽略的。我觉得我正在接近答案,但我不知道该怎么做才能得到这个答案。

Note I希望允许无限数量的子列表

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-15 19:19:44

代码语言:javascript
复制
<?php

$text = "1. dog
1. cat
1. fish
 1. horse
  1. duck
   1. goose
  1. swan
 1. monkey
  1. chimpanzee
  1. orangutan
  1. whale
1. pig
";

function callback($match) {
    $out = preg_replace_callback("/(^($match[2] +)1\. .+(\\n|$))(?1)*/m", 'callback', $match[0]);
    $out = preg_replace("/^$match[2]1\. (.+)$/m", "<li>$1</li>", $out);
    return "<ol>\n$out</ol>\n";
}

$html = preg_replace_callback("/(^( *)1\. .+(\\n|$))(?1)*/m", 'callback', $text);

echo $html;

?>

这是理想的演示

这是一个非常好的主意,递归地使用preg_replace_callback。另外,关于$-strings没有在双引号中插值是正确的,除非它们是一个set变量;我总是忘记这一点。而且,您使用/m是正确的,因为您希望^匹配每一行的开头(而不是整个字符串的开头),并且使用(\n|$)也是正确的,尽管$匹配/m模式下的每一行的末尾-因为否则,量词+将无法工作,因为$实际上不会消耗\n。当我第一次读到你的问题时,我没有看到这些事实。

现在,让我们从第一个表达式开始:

代码语言:javascript
复制
/(^( *)1\. .+(\\n|$))(?1)*/m

实际上,递归子表达式(?1)除了作为速记外没有必要。让我们扩展一下:

代码语言:javascript
复制
/(^( *)1\. .+(\\n|$))(^( *)1\. .+(\\n|$))*/m
 |                  ||                  |
 +------------------++------------------+

所以我们有两个相同的一半。为什么不像你那样使用+呢?因为我只想捕获缩进第一行的空格数。这些空间存储在$match[2]中。

在回调中,我们将这些空格带回来,加上一个或多个空格:

代码语言:javascript
复制
/(^($match[2] +)1\. .+(\\n|$))(?1)*/m

这样,我们只关注当前缩进级别(更多的空格)下的级别,以及每个级别的preg_replace_callback递归。当递归展开时,只有那个级别的空格数$match[2]缩进的行被包装在<li></li>中,

代码语言:javascript
复制
/^$match[2]1\. (.+)$/m

在返回整个包装在<ol></ol>中的内容之前。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19387617

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档