帮助删除领先的空白区域的正则表达式

时间:2009-08-09 02:00:00

标签: php html regex kohana

我正在修改Kohana库的核心功能,即text::auto_p()功能。

该功能将自身描述为“类固醇上的nl2br()”。从本质上讲,它提供<br />个单行换行符,但双换行符用<p>标记包围。

我发现它的局限性在<br />元素中只有<pre>。这将创建双重新行,这不是我想要的。我做了一个修改,用正则表达式来获取pre元素,以及一个将删除<br />的回调函数。

然而,主要的问题是我的文本中的代码示例得到auto_p()'d,我需要保留缩进(为了便于阅读)。对我来说不幸的是,该功能会在行上剥离前导和尾随空白区域。

这是剥离前导空间的正则表达式

$str = preg_replace('~^[ \t]+~m', '', $str);

我不是最好的正则表达式大师,但我非常肯定会说“获得前导空格和标签,其中至少有一个并用空字符串替换它们。”

我已尝试删除此行,但之后它会添加<br />我肯定不想要它们 - 在一种情况下,我得到这样的输出

<ul><br />
    <li>something</li>
</ul>

如何修改此正则表达式或代码以不剥离<pre>元素内的前导空格?

The original helper function from Kohana is available here。 (滚动到几乎底部)。

我知道我会得到一些'使用HTML解析器'类型的答案 - 虽然你可能是正确的 - 现有的代码只是使用正则表达式,我宁愿一个更简单的解决方案(我不需要包括一个图书馆等)。

感谢您的时间。

2 个答案:

答案 0 :(得分:1)

我将如何做到这一点:

$str = preg_replace(
    '~^[ \t]++(?=(?:[^<]++|<(?!/?+pre\b))*+(?:\z|<pre\b))~im',
    '', $str);

在匹配某些行前导空格后,前瞻扫描前面会显示<pre></pre>个标记。前瞻的是这一点:

(?:[^<]++|<(?!/?+pre\b))*+

如果它不是<pre></pre>标记的开头,则匹配左边括号中的零个或多个,左尖括号。该部分只会在遇到<pre>(起始)标记,</pre>(结束)标记或输入结束时停止匹配。如果它是一个停止它的结束标记,你知道你在<PRE>元素内,所以你不想做替换。

占有量词('++''*+''?+')对于防止catastrophic backtracking至关重要。 (我无能为力:这句话总让我想起来自Half-Life共振级联场景。)

这种技术还假设格式合理的HTML,即所有<pre>...</pre>标签都得到了适当的平衡。 SGML评论中的标签也会搞砸 - 除非它们恰好是平衡的。你也可以处理评论,如果你不介意使正则表达式的两倍和丑陋的三倍。 :)

答案 1 :(得分:0)

我的问题已经讨论了很多 - 请查看此链接

http://us3.php.net/manual/en/function.nl2br.php#91828

这个也是:

http://us3.php.net/manual/en/function.nl2br.php#39641