web-dev-qa-db-ja.com

すべてのXHTML / HTML改行(<br>)を新しい行に置き換える方法は?

最高のbr2nl関数を探しています。 <br> </ code>と<br /> </ code>のすべてのインスタンスを改行\nに置き換えます。 nl2br() 関数とよく似ていますが、その逆です。

PHP手動コメントにいくつかの解決策があることを知っていますが、可能な解決策についてSOコミュニティからのフィードバックを探しています。

38
markb

私は通常、「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*
  • オプションとして、//?
  • そして最後に、>
  • #iはHTMLでは有効であるため、大文字と小文字を区別しない一致(<BR>)を使用します。
98
Pascal MARTIN

プラットフォームに依存しない改行を使用するには、PHP_EOL定数を使用する必要があります。

私の意見では、可能な限り正規表現以外の関数を使用すると、コードが読みやすくなります。

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

このソリューションにはいくつかの欠陥があることは承知していますが、私の洞察をまだ共有したいと思っています。

8
Antti

ドキュメントが整形式(または少なくとも整形式っぽい)の場合は、 DOM拡張 およびxpathを使用して、すべてのbr要素を検索し、\ 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();

プリント

<!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>

編集:反復が1つだけの短いバージョン

$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

nl2br コメントから:

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