Я хочу удалить новые строки из некоторого html (с php), за исключением тегов <pre>, где, очевидно, важны пробелы.
Это может быть 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");
Если html хорошо сформирован, вы можете положиться на то, что теги <pre>
не могут быть вложенными. Сделайте два прохода: сначала вы разбиваете входные данные на блок предметки и все остальное. Вы можете использовать регулярное выражение для этой задачи. Затем вы удаляете новые строки из каждого блока без предварительного кода и, наконец, присоединяете их все вместе.
Обратите внимание, что большинство html не очень хорошо сформировано, поэтому этот подход может иметь некоторые ограничения на то, где вы можете его использовать.
Разделите содержимое вверх. Это легко сделать с помощью …
$blocks = preg_split('/<(|\/)pre>/', $html);
Просто будьте осторожны, потому что элементы $ blocks не будут содержать предварительно открывающие и закрывающие теги. Я считаю, что предположить, что HTML допустим, допустимо, и поэтому вы можете ожидать, что преблокируются как все остальные элементы массива (1, 3, 5, …). Легко тестируется с помощью $i % 2 == 1
.
Пример «полный» скрипт (изменить, как вам нужно) …
<?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; ?>