7

現在、PHP と正規表現を使用して、ページからすべての HTML コメントを削除しています。スクリプトはうまく機能します...少しうまくいきすぎます。の条件付きコメントを含むすべてのコメントを削除します。これが私が持っているものです:

<?php
  function callback($buffer)
  {
        return preg_replace('/<!--(.|\s)*?-->/', '', $buffer);
  }

  ob_start("callback");
?>
... HTML source goes here ...
<?php ob_end_flush(); ?>

私の正規表現はあまり熱くないので、次のような条件付きコメントを除外するようにパターンを変更する方法を見つけようとして苦労しています。

<!--[if !IE]><!-->
<link rel="stylesheet" href="/css/screen.css" type="text/css" media="screen" />
<!-- <![endif]-->

<!--[if IE 7]>
<link rel="stylesheet" href="/css/ie7.css" type="text/css" media="screen" />
<![endif]-->

<!--[if IE 6]>
<link rel="stylesheet" href="/css/ie6.css" type="text/css" media="screen" />
<![endif]-->

乾杯

4

5 に答える 5

23

コメントは HTML でネストできないため、理論的には正規表現がその役割を果たします。それでも、特に入力が適切な形式であることが保証されていない場合は、ある種のパーサーを使用することをお勧めします。

これが私の試みです。通常のコメントのみに一致させるには、これでうまくいきます。かなりのモンスターになってしまいました、すみません。かなり広範囲にテストしましたが、うまくいくようですが、保証はしません。

<!--(?!\s*(?:\[if [^\]]+]|<!|>))(?:(?!-->).)*-->

説明:

<!--                #01: "<!--"
(?!                 #02: look-ahead: a position not followed by:
  \s*               #03:   any number of space
  (?:               #04:   non-capturing group, any of:
    \[if [^\]]+]    #05:     "[if ...]"
    |<!             #06:     or "<!"
    |>              #07:     or ">"
  )                 #08:   end non-capturing group
)                   #09: end look-ahead
(?:                 #10: non-capturing group:
  (?!-->)           #11:   a position not followed by "-->"
  .                 #12:   eat the following char, it's part of the comment
)*                  #13: end non-capturing group, repeat
-->                 #14: "-->"

ステップ 02 と 11 は非常に重要です。#02 は、以下の文字が条件付きコメントを示していないことを確認します。その後、#11 は次の文字がコメントの終わりを示していないことを確認し、#12 と #13 は実際の一致を引き起こします。

「global」および「dotall」フラグを使用して適用します。

反対のことを行う (条件付きコメントのみに一致する) には、次のようになります。

<!(--)?(?=\[)(?:(?!<!\[endif\]\1>).)*<!\[endif\]\1>

説明:

<!                  #01: "<!"
(--)?               #02: two dashes, optional
(?=\[)              #03: a position followed by "["
(?:                 #04: non-capturing group:
  (?!               #05:   a position not followed by
    <!\[endif\]\1>  #06:     "<![endif]>" or "<![endif]-->" (depends on #02)
  )                 #07:   end of look-ahead
  .                 #08:   eat the following char, it's part of the comment
)*                  #09: end of non-capturing group, repeat
<!\[endif\]\1>      #10: "<![endif]>" or "<![endif]-->" (depends on #02)

ここでも、「global」フラグと「dotall」フラグを使用して適用します。

ステップ #02 は、「downlevel-revealed」構文によるものです。「MSDN - 条件付きコメントについて」を参照してください。

スペースが許可または期待される場所が完全にはわかりません。必要に応じて式に追加\s*します。

于 2009-06-18T16:52:18.987 に答える
2

1 つの正規表現で動作させることができない場合、またはより多くのコメントを保持したい場合は、preg_replace_callback. 次に、コメントを個別に処理する関数を定義できます。

<?php
function callback($buffer) {
    return preg_replace_callback('/<!--.*-->/U', 'comment_replace_func', $buffer);
}

function comment_replace_func($m) {
    if (preg_match( '/^\<\!--\[if \!/i', $m[0])) {
        return $m[0];   
    }              

    return '';
}   

ob_start("callback");
?>

... HTML source goes here ...

<?php ob_end_flush(); ?>
于 2009-06-18T16:10:30.713 に答える
1

要約すると、これが最良の解決策のようです。

<?php
  function callback($buffer) {
    return preg_replace('/<!--[^\[](.|\s)*?-->/', '', $buffer);
  }
  ob_start("callback");
?>
... HTML source goes here ...
<?php ob_end_flush(); ?>

すべてのコメントを削除し、一番上のものを除いて条件を残します。

<!--[if !IE]><!-->
<link rel="stylesheet" href="/css/screen.css" type="text/css" media="screen" />
<!-- <![endif]-->

追加が問題を引き起こしているようです。

これを考慮してその条件をそのままにしておく正規表現を誰かが提案できれば、それは完璧です。

トマラクのソリューションは良さそうですが、初心者であり、それ以上のガイドラインがないため、実装方法がわかりませんが、誰かが適用方法を詳しく説明できる場合は試してみたいと思いますか?

ありがとう

于 2009-06-23T08:46:03.210 に答える
0

このようなものがうまくいくかもしれません:

/<!--[^\[](.|\s)*?-->/

コメントの開始タグの直後に開始ブラケットがあるコメントを無視することを除いて、それはあなたのものと同じです。

于 2009-06-18T16:06:43.460 に答える
0

PHP の正規表現エンジンが次のようになるかどうかはわかりませんが、次のパターンを試してください。

'/<!--(.|\s)*(\[if .*\]){0}(.|\s)*?-->/'
于 2009-06-18T16:07:04.583 に答える