PHP自动创建从文本文件到(X)HTML的列表

PHP自动创建从文本文件到(X)HTML的列表,php,html,html-lists,Php,Html,Html Lists,我正在创建一个CMS,你可能已经知道,现在我有一个小问题 让我们说: 我有一个包含以下内容的文本文件: [b]Some bold text[/b] [i]Italic[/i] - List item 1 - List item 2 - List item 3 # List item 1 # List item 2 # List item 3 我想把它转换成: <b>Some bold text</b> <i>Italic</i> <ul&g

我正在创建一个CMS,你可能已经知道,现在我有一个小问题

让我们说: 我有一个包含以下内容的文本文件:

[b]Some bold text[/b]
[i]Italic[/i]
- List item 1
- List item 2
- List item 3
# List item 1
# List item 2
# List item 3
我想把它转换成:

<b>Some bold text</b>
<i>Italic</i>
<ul>
    <li>List item 1</li>
    <li>List item 2</li>
    <li>List item 3</li>
</ul>
<ol>
    <li>List item 1</li>
    <li>List item 2</li>
    <li>List item 3</li>
</ol>
一些粗体文本
斜体
  • 清单项目1
  • 清单项目2
  • 清单项目3
  • 清单项目1
  • 清单项目2
  • 清单项目3
  • 粗体和斜体可以工作(使用正则表达式),但是我如何处理列表呢

    “-”列表应转换为

    <ul>
        <li>List item 1</li>
        <li>List item 2</li>
        <li>List item 3</li>
    </ul>
    
    • 清单项目1
    • 清单项目2
    • 清单项目3
    而“#”列表

    
    
  • 清单项目1
  • 清单项目2
  • 清单项目3

  • 有人有这方面的经验吗?请帮帮我。我使用PHP5.2.9

    < P>您可以考虑使用另一种标记语言,如OR。然后,您只需要处理一个库。

    您可以考虑使用另一种标记语言,如OR。然后您只需要处理一个库。

    如果您不想使用现有的解析库,您必须逐行解析文件,并将当前状态保留在某个位置

    如果行以“-”开头,并且州政府告诉您您还没有在列表中,请将a
      加上a
    • 。如果您已经在列表中,只需输入

    • 以“#”开头的行也是如此

      如果不想使用现有的解析库,则必须逐行解析文件,并将当前状态保留在某个位置

      如果行以“-”开头,并且州政府告诉您您还没有在列表中,请将a
        加上a
      • 。如果您已经在列表中,只需输入

      • 以“#”开头的行也是一样,好的,所以不需要所有的降价…
        但是为什么不直接使用你需要的功能呢

        我调整了列表处理功能,使其按程序工作。
        为了最小化文件大小,我压缩了详细的正则表达式
        并删除了与其他降价相关的评论。
        它的时钟为3308字节

        也许对你的口味来说还是太臃肿了。。。d-:
        但你可以自由地走更多的弯路和移除东西。
        例如,您可能不需要嵌套列表

        修改后的代码如下。
        首先是许可证:

        PHP降价 版权所有(c)2004-2009米歇尔·福廷

        版权所有

        基于降价
        版权所有(c)2003-2006约翰·格鲁伯

        版权所有

        以源代码和二进制形式重新分发和使用,带或不带 如果满足以下条件,则允许修改 会议:

        • 源代码的重新分发必须保留上述版权声明, 此条件列表和以下免责声明

        • 以二进制形式重新分发必须复制上述版权 请注意,此条件列表和中的以下免责声明 随分发提供的文件和/或其他材料

        • 无论是“降价”还是其贡献者的名字都不能 用于认可或推广源自此软件的产品 未经事先书面许可

        本软件由版权所有人和贡献者“作为 以及任何明示或暗示的保证,包括但不限于 对于,对适销性和适用性的默示保证 特殊用途不作声明。在任何情况下,版权所有人不得 或出资人对任何直接、间接、附带、特殊、, 惩戒性或间接损害(包括但不限于, 替代货物或服务的采购;使用、数据或服务的损失 利润;或业务中断),无论是何种原因造成的 责任,无论是合同责任、严格责任还是侵权责任(包括 因使用本文件而产生的任何疏忽或其他原因) 软件,即使已告知此类损坏的可能性


        好的,所以您不需要所有的降价…
        但是为什么不直接使用你需要的功能呢

        我调整了列表处理功能,使其按程序工作。
        为了最小化文件大小,我压缩了详细的正则表达式
        并删除了与其他降价相关的评论。
        它的时钟为3308字节

        也许对你的口味来说还是太臃肿了。。。d-:
        但你可以自由地走更多的弯路和移除东西。
        例如,您可能不需要嵌套列表

        修改后的代码如下。
        首先是许可证:

        PHP降价 版权所有(c)2004-2009米歇尔·福廷

        版权所有

        基于降价
        版权所有(c)2003-2006约翰·格鲁伯

        版权所有

        以源代码和二进制形式重新分发和使用,带或不带 如果满足以下条件,则允许修改 会议:

        • 源代码的重新分发必须保留上述版权声明, 此条件列表和以下免责声明

        • 以二进制形式重新分发必须复制上述版权 请注意,此条件列表和中的以下免责声明 随分发提供的文件和/或其他材料

        • 无论是“降价”还是其贡献者的名字都不能 用于认可或推广源自此软件的产品 未经事先书面许可

        本软件由版权所有人和贡献者“作为 以及任何明示或暗示的保证,包括但不限于 对于,对适销性和适用性的默示保证 特殊用途不作声明。在任何情况下,版权所有人不得 或出资人对任何直接、间接、附带、特殊、, 惩戒性或间接损害(包括但不限于, 替代货物或服务的采购;使用、数据的丢失,
        <ol>
            <li>List item 1</li>
            <li>List item 2</li>
            <li>List item 3</li>
        </ol>
        
        <?php
        @define('MARKDOWN_TAB_WIDTH', 4);
        $tab_width = MARKDOWN_TAB_WIDTH;
        $list_level = 0;
        
        function doLists($text) {
        # Form HTML ordered (numbered) and unordered (bulleted) lists.
            global $tab_width, $list_level;
            $less_than_tab = $tab_width - 1;
            # Re-usable patterns to match list item bullets and number markers:
            $marker_ul_re  = '[*-]';
            $marker_ol_re  = '\d+[\.]';
            $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
            $markers_relist = array(
                $marker_ul_re => $marker_ol_re,
                $marker_ol_re => $marker_ul_re,
                );
            foreach ($markers_relist as $marker_re => $other_marker_re) {
                # Re-usable pattern to match any entirel ul or ol list:
                $whole_list_re = '((([ ]{0,'.$less_than_tab.'})('.$marker_re.')[ ]+)(?s:.+?)(\z|\n{2,}(?=\S)(?![ ]*'.$marker_re.'[ ]+)|(?=\n\3'.$other_marker_re.'[ ]+)))'; // mx
                # We use a different prefix before nested lists than top-level lists.
                # See extended comment in _ProcessListItems().
                if ($list_level) {
                    $text = preg_replace_callback('{
                            ^
                            '.$whole_list_re.'
                        }mx',
                        '_doLists_callback', $text);
                    }
                else {
                    $text = preg_replace_callback('{
                            (?:(?<=\n)\n|\A\n?) # Must eat the newline
                            '.$whole_list_re.'
                        }mx',
                        '_doLists_callback', $text);
                    }
                }
            return $text;
            }
        
        function _doLists_callback($matches) {
        # Re-usable patterns to match list item bullets and number markers:
            $marker_ul_re  = '[*+-]';
            $marker_ol_re  = '\d+[\.]';
            $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
            $list = $matches[1];
            $list_type = preg_match("/$marker_ul_re/", $matches[4]) ? "ul" : "ol";
            $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re );
            $list .= "\n";
            $result = processListItems($list, $marker_any_re);
            $result = "<$list_type>\n" . $result . "</$list_type>";
            return "\n". $result ."\n\n";
            }
        
        function processListItems($list_str, $marker_any_re) {
        #   Process the contents of a single ordered or unordered list, splitting it
        #   into individual list items.
        # The $list_level global keeps track of when we're inside a list.
        # Each time we enter a list, we increment it; when we leave a list,
        # we decrement. If it's zero, we're not in a list anymore.
            global $list_level;
            $list_level++;
        # trim trailing blank lines:
            $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
            $list_str = preg_replace_callback('{(\n)?(^[ ]*)('.$marker_any_re.'(?:[ ]+|(?=\n)))((?s:.*?))(?:(\n+(?=\n))|\n)(?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n))))}xm','_processListItems_callback', $list_str);
            $list_level--;
            return $list_str;
            }
        
        function _processListItems_callback($matches) {
            $item = $matches[4];
            $leading_line =& $matches[1];
            $leading_space =& $matches[2];
            $marker_space = $matches[3];
            $tailing_blank_line =& $matches[5];
            if ($leading_line || $tailing_blank_line
            || preg_match('/\n{2,}/', $item))
                { # Replace marker with the appropriate whitespace indentation
                $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item;
                $item = outdent($item)."\n";
                }
            else { # Recursion for sub-lists:
                $item = doLists(outdent($item));
                $item = preg_replace('/\n+$/', '', $item);
                }
            return "<li>" . $item . "</li>\n";
            }
        
        function outdent($text) {
        # Remove one level of line-leading tabs or spaces
            global $tab_width;
            return preg_replace('/^(\t|[ ]{1,'.$tab_width.'})/m', '', $text);
            }
        ?>