1

我正在修改 Kohana 库的一个核心函数text::auto_p()函数。

该函数将自己描述为“nl2br() on steroids”。本质上,它提供<br />单换行符,但双换行符被<p>标签包围。

我发现它的限制是它只会<br />在一个<pre>元素中。这将创建双新行,这不是我想要的。我已经进行了修改,以使用正则表达式拾取 pre 元素,以及一个回调,它将删除<br />哪些工作正常。

但是,主要问题是我的文本中有代码示例,auto_p()我需要保留缩进(为了便于阅读)。对我来说不幸的是,该功能会去除行上的前导和尾随空白。

这是去除前导空格的正则表达式

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

我不是最好的正则表达式大师,但我很确定它说“在至少有一个空格和制表符的地方获取前导空格和制表符,并用空字符串替换它们。”

我试过删除这条线,但它会<br />在我绝对不想要的地方添加 - 在一种情况下,我得到这样的输出

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

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

Kohana 的原始辅助函数可在此处获得。(滚动到几乎底部)。

我知道我会得到一些“使用 HTML 解析器”类型的答案 - 虽然你可能是正确的 - 现有代码只是使用正则表达式,我更喜欢更简单的解决方案(我不必包含库等) .

谢谢你的时间。

4

1 回答 1

1

这是我的做法:

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

在匹配一些行前空白后,前瞻会向前扫描<pre></pre>标记。前瞻的内容是这样的:

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

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

所有格量词('++'、、'*+''?+')对于防止灾难性的回溯是必不可少的。(我忍不住:这句话总是让我想起《半条命》中的共振级联场景。)

该技术还假定 HTML 格式合理,即所有<pre>...</pre>标签都适当平衡。SGML 注释中的标签也会搞砸——除非它们恰好是平衡的。如果您不介意将正则表达式设置为两倍长和三倍丑陋,您也可以处理注释。:)

于 2009-08-09T03:44:51.823 回答