2

我有一个文本字段,用户可以在其中编写特定命令来获取一些 html。

例如:

Text Text Text Text

[*] first entry
[*] second entry
[*] 3rd...

Text Text

此文本应使用正则表达式转换为如下内容:

text text

<ol>
 <li>FirstEntry</li>
 <li>Second</li>
 ..
</ol>

text text

有什么建议吗?

与 entry 匹配的正则表达式是这样的:

/\[\*\].+/i

问题是如何正确插入<ol></ol>

我的解决方案

我在想我可以解析所有文本行,当解析器遇到以 [*] 开头的第一行然后<ol></ol>

到目前为止,我已经制作了将单曲[*] ...转换为的脚本<li> ...

http://codepad.org/yzRVupON

preg_replace('/\[\*\](.+)/i','<li>$1</li>',$str);

我需要这个<ol>部分

我的实现

http://codepad.org/NNgC6uko

4

3 回答 3

2

用正则表达式进行这种解析可能不是要走的路;对于非常简单的场景可能没问题,但是您尝试添加的功能越多,它就越难——直到它变得无法维护。

我建议从各种 MarkDown 解析器那里借用解析技术;有关更多信息,请参阅这些 问题(还有其他问题)。

回到最初的问题:如果您仅限于使用正则表达式,您可以尝试首先将整个“列表块”与类似的东西匹配

/^(\s*\[\*\].*?$)+/m

(多行模式修饰符是必不可少的)

然后,您可以使用当前的正则表达式将匹配的文本分解为单独的列表项,然后用<ol></ol>.

于 2012-11-10T15:07:02.527 回答
1

为什么不用preg_replace把标签放在两边呢?可能像下面这样。

$string = <<<EOF
Text Text Text Text

[*] first entry
[*] second entry
[*] 3rd...

Text Text
EOF;

$pattern = '/(\[\*\])([\d\D]+)(\[\*\].*)/';
$replacement = '<ol> ${1}${2}${3} </ol>';
$string = preg_replace($pattern, $replacement, $string);

$pattern = '/\[\*\](.+)/i';
$replacement = '<li>${1}</li>';

echo  preg_replace($pattern, $replacement, $string);

输出:

Text Text Text Text

    <ol>
        <li> first entry </li>
        <li> second entry </li>
        <li> tag 3rd... </li>
    </ol>

Text Text
于 2012-11-10T15:06:59.643 回答
1

这就是我的实现。工作代码:http ://codepad.org/NNgC6uko

这个脚本很容易定制,可以从命令到 HTML 的任何类型的翻译

function parseText($txt) {

    $lines = preg_split('/[\r\n]+/',$txt,null,PREG_SPLIT_NO_EMPTY);
    $newLines = array();

    $lastTag = '';
    foreach($lines as $k=>$v) {

        $currentTag = $v[0];

        //$newLine = $v;
        $newLine = preg_replace('/^\* (.+)$/','<li>$1</li>',$v);

        if ($currentTag=='*' && $lastTag != '*')
            $newLines[] = '<ol>';

        else if ( $lastTag == '*' && $currentTag != '*' )
            $newLines[] = '</ol>';  

        $newLines[] = $newLine;



        $lastTag = $currentTag;

    }

    print_r($newLines);
}
于 2012-11-10T15:42:20.147 回答