web-dev-qa-db-fra.com

Comment remplacer tous les sauts de ligne XHTML / HTML (<br>) par de nouvelles lignes?

Je recherche le meilleur br2nl fonction. Je souhaite remplacer toutes les instances de <br></code> et <br /></code> avec des nouvelles lignes \n. Tout comme la fonction nl2br () mais le contraire.

Je sais qu'il existe plusieurs solutions dans les commentaires manuels PHP), mais je cherche des commentaires de la communauté SO sur les solutions possibles.

38
markb

Je dirais généralement "n'utilisez pas de regex pour travailler avec HTML", mais, sur celui-ci, j'irais probablement avec une regex, considérant que <br> les balises ressemblent généralement à:

  • <br>
  • ou <br/>, avec n'importe quel nombre d'espaces avant le /


Je suppose que quelque chose comme ça ferait l'affaire:

$html = 'this <br>is<br/>some<br />text <br    />!';
$nl = preg_replace('#<br\s*/?>#i', "\n", $html);
echo $nl;

Quelques notes:

  • commence avec <br
  • suivi d'un nombre quelconque de caractères blancs: \s*
  • optionnellement, un /: /?
  • et, enfin, un >
  • et ceci en utilisant une correspondance insensible à la casse (#i), comme <BR> serait valide en HTML
98
Pascal MARTIN

Vous devriez utiliser PHP_EOL constante pour avoir des retours à la ligne indépendants de la plate-forme.

À mon avis, l'utilisation de fonctions non-regexp autant que possible rend le code plus lisible.

$newlineTags = array(
  '<br>',
  '<br/>',
  '<br />',
);
$html = str_replace($newlineTags, PHP_EOL, $html);

Je suis conscient que cette solution a quelques défauts, mais je voulais quand même partager mes idées.

8
Antti

Si le document est bien formé (ou du moins bien formé), vous pouvez utiliser extension DOM et xpath pour rechercher et remplacer tous les éléments br par un nœud de texte\n.

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

impressions

<!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: version plus courte avec une seule itération

$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();
1
VolkerK

À partir des commentaires nl2br :

<?php
function br2nl($string){
  $return=eregi_replace('<br[[:space:]]*/?'.
    '[[:space:]]*>',chr(13).chr(10),$string);
  return $return;
}
?> 
0
ssergei