我正在修改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解析器'类型的答案 - 虽然你可能是正确的 - 现有的代码只是使用正则表达式,我宁愿一个更简单的解决方案(我不需要包括一个图书馆等)。
感谢您的时间。
答案 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)