Замените пробелы & nbsp; между тегами PRE

Мне нужно расширить функциональные возможности следующего фрагмента кода для преобразования пространств – только между тегами PRE в строке, содержащей html:

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> 

 $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); 

Взял меня немного … Но это работает.

Вы можете использовать парсер DOM. Вот как вы это сделаете, используя собственные функции DOM для PHP:

 <?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() . Другая возможность – использовать регулярное выражение, которого я избежал в первую очередь.