有人问similar question,但接受的答案不符合我的要求。
输入:
<strong>bold <br /><br /> text</strong><br /><br /><br />
<a href="#">link</a><br /><br />
<pre>some code</pre>
I'm a single br, <br /> leave me alone.
预期输出:
<p><strong>bold <br /> text</strong><br /></p>
<p><a href="#">link</a><br /></p>
<pre>some code</pre>
<p>I'm a single br, <br /> leave me alone.</p>
我上面提到的接受的答案会将多个br转换为p,最后将所有输入换成另一个p。但在我的情况下,你不能将pre包装在p标签内。有人可以帮忙吗?
此编辑之前的预期输出有点令人困惑。重点是:
将多个br转换为单个br(使用preg_replace('/(<br />)+/', '<br />', $str);
实现)
检查内联元素和未解包的文本(在这种情况下没有父元素,输入来自$ _POST)并使用&lt; p&gt;换行,只保留块级元素。
答案 0 :(得分:3)
不使用正则表达式。为什么?请参阅:RegEx match open tags except XHTML self-contained tags
使用适当的DOM操纵器。请参阅:http://php.net/manual/en/book.dom.php
编辑:
我真的不喜欢提供食谱 - 食谱,所以这里有一个解决方案,可以将<br />
的{{1}}更改为包裹在<p></p>
中的文字:
script.php:
<?php
function isBlockElement($nodeName) {
$blockElementsArray = array("pre", "div"); // edit to suit your needs
return in_array($nodeName, $blockElementsArray);
}
function hasBlockParent(&$node) {
if (!($node instanceof DOMNode)) {
// return whatever you wish to return on error
// or throw an exception
}
if (is_null($node->parentNode))
return false;
if (isBlockElement($node->parentNode))
return true;
return hasBlockParent($node->parentNode);
}
$myDom = new DOMDocument;
$myDom->loadHTMLFile("in-file");
$myDom->normalizeDocument();
$elems =& $myDom->getElementsByTagName("*");
for ($i = 0; $i < $elems->length; $i++) {
$element =& $elems->item($i);
if (($element->nextSibling->nodeName == "br" && $element->nextSibling->nextSibling->nodeName == "br") && !hasBlockParent($element)) {
$parent =& $element->parentNode;
$parent->removeChild($element->nextSibling->nextSibling);
$parent->removeChild($element->nextSibling);
// check if there are further nodes on the same level
$nSibling;
if (!is_null($element->nextSibling))
$nSibling = $element->nextSibling;
else
$nSibling = NULL;
// delete the old node
$saved = $parent->removeChild($element);
$newNode = $myDom->createElement("p");
$newNode->appendChild($saved);
if ($nSibling == NULL)
$parent->appendChild($newNode);
else
$parent->insertBefore($newNode, $nSibling);
}
}
$myDom->saveHTMLFile("out-file");
?>
这不是一个完整的解决方案,但它是一个起点。这是我在午休期间写的最好的,请记住我上次用PHP编写的时间大约是2年前(从那时起主要做的是C ++)。我不是把它写成一个完整的解决方案,而是给你一个......好吧,起点:)
无论如何,输入文件:
[dare2be@schroedinger dom-php]$ cat in-file
<strong>bold <br /><br /> text</strong><br /><br /><br />
<a href="#">link</a><br /><br />
<pre>some code</pre>
I'm a single br, <br /> leave me alone.
输出文件:
[dare2be@schroedinger dom-php]$ cat out-file
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p><strong>bold <br><br> text</strong></p><br><p><a href="#">link</a></p><pre>some code</pre>
I'm a single br, <br> leave me alone.</body></html>
整个DOCTYPE
mumbo jumbo是副作用。代码不会执行您所说的其他内容,例如将<bold><br><br></bold>
更改为<bold><br></bold>
。此外,这整个脚本是快速草稿,但你会明白这一点。
答案 1 :(得分:2)
好吧,我得到了答案,我相信这会很好用。
来自WordPress ...... wpautop
function。
我用输入(来自我的问题)对它进行了测试,输出几乎与我预期的相同,我只需要稍微修改它以满足我的需要。
感谢dare2be,但我对PHP中的DOM操纵器不是很熟悉。