Заменить переводы строк тегами BR, но только внутри тегов PRE - PullRequest
3 голосов
/ 04 октября 2009

В наличии PHP5, что является хорошим preg_replace выражением для этого преобразования:

заменить символы новой строки на <br />, но только в пределах <pre> блоков

(Не стесняйтесь делать упрощающие предположения и игнорировать угловые случаи. Например, мы можем Предположим, что теги будут одной строкой, а не патологическими вещами вроде)

Введите текст:

<code><div><pre class='some class'>1
2
3
line 1
line 2
line 3

Выход:

<code><div><pre>1<br />2<br />3<br />
line 1<br />line 2<br />line 3<br />

(Мотивирующий контекст: попытка закрыть ошибку 20760 в расширении SyntaxHighlight_GeSHI в Викискладе и найти мои навыки работы с PHP (я в основном использую Python) не до конца

Я открыт для других решений, кроме regexen, но предпочтение отдается маленькому (например, сборка html-машин разбирается излишне).

Ответы [ 2 ]

6 голосов
/ 04 октября 2009

Как то так?

<code><?php

$content = "<div><pre class='some class'>1
2
3
line 1
line 2
line 3
«; функция getInnerHTML ($ Node) { $ Body = $ Node-> ownerDocument-> documentElement-> firstChild-> firstChild; $ Document = new DOMDocument (); $ Document-> AppendChild ($ Document-> importNode ($ Body, правда)); return $ Document-> saveHTML (); } $ dom = новый DOMDocument (); $ dom-> loadHTML ($ content); $ preElements = $ dom-> getElementsByTagName ('pre'); if (count ($ preElements)) { foreach ($ preElements как $ pre) { $ value = preg_replace ('/ \ n | \ r \ n /', '
', $ pre-> nodeValue); $ pre-> nodeValue = $ value; } echo html_entity_decode (getInnerHTML ($ dom-> documentElement)); }
0 голосов
/ 05 октября 2009

Основано на том, что сказал SilentGhost (который по какой-то причине здесь не показывается):

<code><?php
$str = "<div><pre class='some class' >1
2
3
< / pre>
<pre>line 1
line 2
line 3
"; $ out = "
 1 
2
3
line 1<br />line 2<br />line 3<br />
"; функция protect_newlines ($ str) { // \ n ->
, но только если он находится в предварительном блоке // защищает новые строки от Parser :: doBlockLevels () / * разделить на
, в основном. наверное достаточно хорош * /
    $ str = "". $ str; // разделение гарантии будет на четных позициях
    // $ parts = preg_split ('/ () / Umsxu', $ str, -1, PREG_SPLIT_DELIM_CAPTURE);
    $ parts = preg_split ("/ (<\ s * pre. * \ / \ s * pre \ s *>) / Umsxu", $ str, -1, PREG_SPLIT_DELIM_CAPTURE);
    foreach ($ parts as $ idx => $ part) {
        if ($ idx% 2) {
            $ parts [$ idx] = preg_replace ("/ \ n /", "
", $ part); } } $ str = implode ('', $ parts); / * отрубить первый пробел, который мы добавили * / вернуть substr ($ str, 1); } assert (protect_newlines ($ str) === $ out); ?>
...