【发布时间】:2012-07-16 12:59:41
【问题描述】:
我有这个功能(我在 Stackoverflow 的某处找到)自动在输出字符串中添加<p> 标签。
function autop ($string) {
// Define block tags
$block_tag_list = array ('address', 'applet', 'article', 'aside', 'audio', 'blockquote', 'button', 'canvas', 'center', 'command', 'data', 'datalist', 'dd', 'del', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'iframe', 'ins', 'isindex', 'li', 'map', 'menu', 'nav', 'noframes', 'noscript', 'object', 'ol', 'output', 'p', 'pre', 'progress', 'section', 'script', 'summary', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'ul', 'video');
$tags = '<' . implode ('[^>]*>|<', $block_tag_list) . '[^>]*>';
$pattern = <<<PATTERN
/
(\A|\\n\\n)(?!$tags) # Start of string or two linebreaks or anything but a block tag
(.+?) # Just about anything
(\Z|\\n\\n) # End of string or two line breaks
/isex
PATTERN;
$string = str_replace ("\r\n", "\n", $string);
$string = str_replace ("\r\t", "", $string);
$string = str_replace ("\n\t", "", $string);
$string = str_replace ("\t", "", $string);
$string = preg_replace ($pattern, "'\\1<p>' . nl2br ('\\2') . '</p>\\3'", $string);
$string = preg_replace ($pattern, "'\\1<p>' . nl2br ('\\2') . '</p>\\3'", $string);
$string = str_replace ('\"', """, $string);
return $string;
}
有这种类型的字符串:
<h1>Title</h1>
This will be wrapped in a p tag
This should be wrapped in a p tag too
输出
<h1>Title</h1>
<p>This will be wrapped in a p tag</p>
<p>This should be wrapped in a p tag too</p>
它工作正常,但有一个问题:它将紧跟在<p> 标记之后的HTML 标记包装在其他<p> 标记中,从而搞砸了代码。如果 HTML 标记位于 <h1> 或任何其他块标记之后,则不会发生这种情况。
将双 preg_replace 设置为单个可以解决问题,但是如果像之前的示例那样有两个段落,它只会包装第一个而不是第二个。
我觉得这只是一个很小的变化,可以让它“滴答作响”,但我想不通。
也许如果有人有一个天才的罢工...... :)
【问题讨论】:
-
规则 1) 不要在 html 上使用正则表达式。规则 2) 如果在 html 上使用正则表达式,请参阅规则 #1。
-
供参考,autop通常指Wordpress函数:codex.wordpress.org/Function_Reference/wpautop