Как заменить все перерывы строк XHTML/HTML (<br>) на новые строки?
Я ищу лучшую br2nl
функцию. Я хотел бы заменить все экземпляры <br>
и <br />
на строки новой строки \n
. Как и функция nl2br(), но наоборот.
Я знаю, что в комментариях к PHP есть несколько решений, но я ищу отзывы от сообщества SO о возможных решениях.
Ответы
Ответ 1
Я бы сказал "не использовать регулярное выражение для работы с HTML", но в этом случае я, вероятно, поеду с регулярным выражением, считая, что теги <br>
обычно выглядят так:
-
<br>
- или
<br/>
, с любым количеством пробелов перед /
Я предполагаю, что что-то подобное сделало бы трюк:
$html = 'this <br>is<br/>some<br />text <br />!';
$nl = preg_replace('#<br\s*/?>#i', "\n", $html);
echo $nl;
Пара примечаний:
- начинается с
<br
- за которым следует любое количество белых символов:
\s*
- optionnaly, a
/
: /?
- и, наконец, a
>
- и это с использованием нечувствительного к регистру совпадения (
#i
), поскольку <br>
будет действительным в HTML
Ответ 2
Вы должны использовать константу PHP_EOL
, чтобы иметь независимые от новой строки строки.
По-моему, использование неповторяющихся функций по возможности делает код более читаемым.
$newlineTags = array(
'<br>',
'<br/>',
'<br />',
);
$html = str_replace($newlineTags, PHP_EOL, $html));
Я знаю, что это решение имеет некоторые недостатки, но мне хотелось еще раз поделиться своими соображениями.
Ответ 3
Если документ хорошо сформирован (или, по крайней мере, правильно сформирован), вы можете использовать расширение DOM и xpath, чтобы найти и замените все элементы br на \n текст node.
$in = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html><head><title>...</title></head><body>abc<br />def<p>ghi<br />jkl</p></body></html>';
$doc = new DOMDOcument;
$doc->loadhtml($in);
$xpath = new DOMXPath($doc);
$toBeReplaced = array();
foreach($xpath->query('//br') as $node) {
$toBeReplaced[] = $node;
}
$linebreak = $doc->createTextNode("\n");
foreach($toBeReplaced as $node) {
$node->parentNode->replaceChild($linebreak->cloneNode(), $node);
}
echo $doc->savehtml();
печатает
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head><title>...</title></head>
<body>abc
def<p>ghi
jkl</p>
</body>
</html>
edit: более короткая версия с одной итерацией
$in = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html><head><title>...</title></head><body>abc<br />def<p>ghi<br />jkl</p></body></html>';
$doc = new DOMDOcument;
$doc->loadhtml($in);
$xpath = new DOMXPath($doc);
$linebreak = $doc->createTextNode("\n");
foreach($xpath->query('//br') as $node) {
$node->parentNode->removeChild($node);
}
echo $doc->savehtml();
Ответ 4
Из nl2br комментарии:
<?php
function br2nl($string){
$return=eregi_replace('<br[[:space:]]*/?'.
'[[:space:]]*>',chr(13).chr(10),$string);
return $return;
}
?>