Удаление новых строк, кроме <pre class="prettyprint-override">

Я хочу удалить новые строки из некоторого html (с php), кроме как <pre> теги, где явно важны пробелы.

Ответ 1

Это может быть 3 года спустя, но... Следующий код удалит все разрывы строк и пробелы, пока он не находится за пределами предварительных тегов. Ура!

function sanitize_output($buffer)
{
    $search = array(
        '/\>[^\S ]+/s', //strip whitespaces after tags, except space
        '/[^\S ]+\</s', //strip whitespaces before tags, except space
        '/(\s)+/s'  // shorten multiple whitespace sequences
        );
    $replace = array(
        '>',
        '<',
        '\\1'
        );

    $blocks = preg_split('/(<\/?pre[^>]*>)/', $buffer, null, PREG_SPLIT_DELIM_CAPTURE);
    $buffer = '';
    foreach($blocks as $i => $block)
    {
      if($i % 4 == 2)
        $buffer .= $block; //break out <pre>...</pre> with \n's
      else 
        $buffer .= preg_replace($search, $replace, $block);
    }

    return $buffer;
}

ob_start("sanitize_output");

Ответ 2

Если html хорошо сформирован, вы можете положиться на то, что теги <pre> не могут быть вложенными. Сделайте два прохода: сначала вы разбиваете входные данные на блок предметки и все остальное. Вы можете использовать регулярное выражение для этой задачи. Затем вы удаляете новые строки из каждого блока без предварительного кода и, наконец, присоединяете их все вместе.

Обратите внимание, что большинство html не очень хорошо сформировано, поэтому этот подход может иметь некоторые ограничения на то, где вы можете его использовать.

Ответ 3

Разделите содержимое вверх. Это легко сделать с помощью...

$blocks = preg_split('/<(|\/)pre>/', $html);

Просто будьте осторожны, потому что элементы $blocks не будут содержать предварительно открывающие и закрывающие теги. Я считаю, что предположить, что HTML допустим, допустимо, и поэтому вы можете ожидать, что преблокируются как все остальные элементы массива (1, 3, 5,...). Легко проверяется с помощью $i % 2 == 1.

Пример "complete" script (измените, как вам нужно)...

<?php
//out example HTML file - could just as easily be a read in file
$html = <<<EOF
<html>
  <head>
    <title>test</title>
  </head>
  <body>
    <h1>Title</h1>
    <p>
      This is an article about...
    </p>
    <pre>
      line one
      line two
      line three
    </pre>
    <div style="float: right:">
      random
    </div>
    </body>
</html>
EOF;

//break it all apart...
$blocks = preg_split('/<(|\/)pre>/', $html);

//and put it all back together again
$html = ""; //reuse as our buffer
foreach($blocks as $i => $block)
{
  if($i % 2 == 1)
    $html .= "\n<pre>$block</pre>\n"; //break out <pre>...</pre> with \n's
  else 
    $html .= str_replace(array("\n", "\r"), "", $block, $c);
}

echo $html;
?>