将空格替换为&;nbsp;PRE标签之间


Replace spaces with   between PRE tags

我需要扩展以下代码片段的功能,以便在包含html:的字符串中的PRE标记之间仅转换空格

str_replace(' ',' ',$str);

例如,如果$str包含以下字符串;

<p>abc 123</p>
<pre class="abc" id="123">abcedfg 12345</pre>

它将被转换为:

<p>abc 123</p>
<pre class="abc" id="123">abcedfg&nbsp;12345</pre>

类似地;

<p>abc 123</p>
<pre>abcedfg 12345</pre>

将转换为:

<p>abc 123</p>
<pre>abcedfg&nbsp;12345</pre>

您可以使用DOM解析器。以下是使用PHP原生DOM函数的方法:

<?php
$test = '
<p>abc 123</p>
<pre class="abc" id="pre123">abcedfg 12345</pre>
<p>abc 123</p>
<pre class="abc" id="pre456">abcedfg 12345</pre>
<div>
    <div>
        <div>
            <pre class="abc" id="pre789">abcedfg 12345</pre>
        </div>
    </div>
</div>
';
$dom = new DOMDocument("1.0");
$dom->loadHTML($test);
$xpath = new DOMXpath($dom);
$pre = $xpath->query("//pre");
foreach($pre as $e) {
    $e->nodeValue = str_replace(" ", "&nbsp;", $e->nodeValue);
}
echo $dom->saveHTML();

输出

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>abc 123</p>
<pre class="abc" id="pre123">abcedfg&nbsp;12345</pre>
<p>abc 123</p>
<pre class="abc" id="pre456">abcedfg&nbsp;12345</pre>
<div>
    <div>
        <div>
            <pre class="abc" id="pre789">abcedfg&nbsp;12345</pre>
        </div>
    </div>
</div></body></html>

编辑:

我不知道如何去掉doctype/html/body标记。在PHP>=5.3.6上工作的一个可能的解决方案是指定在saveHTML()方法中输出哪个节点。另一种可能性是使用regex,我一开始就避免使用它。

$text = '<pre>test 1234 123</pre>';
$text2 = '<pre class="test">test 1234 123</pre>';
function testreplace($text) {
    return preg_replace_callback('/['<]pre(.*)['>](.*)['<]'/pre['>]/i', 
        create_function(
            '$matches',
            'return "<pre".$matches[1].">".str_replace(" ", "&nbsp;", $matches[2])."</pre>'n";'
        ), $text);
}
echo testreplace($text);
echo testreplace($text2);

我花了一段时间。。。但它是有效的。