プログラミング

正規表現でHTMLコメントを取り除くには

2007年11月19日

HTMLコメントを削除する方法

2008/02/19 改定
<pre><?php
$html='outside <!--[inside]--> outside <!--[inside]--> outside';
echo htmlspecialchars(preg_replace('/<!--[\s\S]*-->/','',$html));                  // 1)
echo '<br />-----<br />';
echo htmlspecialchars(preg_replace('/<!--([^-]|-[^-]|--[^>])*-->/','',$html));     // 2)
echo '<br />-----<br />';
echo htmlspecialchars(preg_replace('/<!--(([^-]|-[^-]|--[^>])*)-->/','$1',$html)); // 3)
echo '<br />-----<br />';
echo htmlspecialchars(preg_replace('/<!--(([^-]|-[^-]|--[^>])*)-->/','$2',$html)); // 4)
echo '<br />-----<br />';
echo htmlspecialchars(preg_replace('/<!--[\s\S]*?-->/','',$html));                 // 5)


実行結果

outside  outside
-----
outside  outside  outside
-----
outside [inside] outside [inside] outside
-----
outside ] outside ] outside
-----
outside  outside  outside

単に『<!--』と『-->』の間を『[\s\S]*』で認識する1の方法だと、最初の『<!--』と最後の『-->』が認識されて、だめ。

2は、『-->』を含まない文字を認識する方法。元ネタはこちら

5は、幸之介さんにコメントをいただいてテストした方法。これのほうが2より簡単明快で、おそらくスピードも速い。

ところで、3のケースだと括弧が入れ子になっているが、$1 として認識されるのは外側らしい。内側の括弧に相当する $2 に代入されるのは、最後に使われた文字列である『 ] 』だ(4を参照)。繰り返し呼ばれることで $2 $3 $4 $5 のように連続してセットされることは無いようで、このような利用の仕方でメモリが大量に消費されることは無いと思われる。

もう一つ考察であるが、『 - 』をエスケープしていない。この文字は『 [a-z] 』の様に利用されるのであるが、このシンタックスに当てはまらない場合はエスケープしないでよいようである。

コメント

幸之介 (2008年2月18日 17:35:52)

『[\s\S]*?』で済むと思われます。ハテナを付けて最小一致。

Kat (2008年2月19日 10:33:19)

あ、本当だ。勉強になりました。ありがとうございます。

というわけで、2008/2/19 改定です。

IIDA Yosiaki (2013年9月19日 21:47:41)

.*?で済むと思われます。

Katsumi (2013年9月20日 10:16:02)

『.*?』だと、複数行に対応できないのではないでしょうか?

コメント送信