2009-06-18 8 views
5

現在、PHPと正規表現を使用してページからすべてのHTMLコメントを取り除いています。スクリプトはうまくいく...少しうまくいく。それは、私の条件付きコメントを含むすべてのコメントを削除します。ここで私が持っているものです: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]--> 

をこのような

答えて

20

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"フラグで適用します。

反対(試合のみ条件付きコメント)を行うために、それはこのようなものになるだろう:、再び

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

"グローバル" と "DOTALL" フラグを適用します。

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

説明。

ステップ#02は、「レベルが下がった」構文のため、"MSDN - About Conditional Comments"を参照してください。

空白が許可されているか期待されているかは完全にはわかりません。適切な場合は式に\s*を追加します。要約すると

+0

こんにちはTomalak、あなたの入力と詳細な説明に感謝します。正規表現をはるかに簡単にする:)。しかし、私はあなたのソリューションを試したところ、空白のページを除いて何も表示しません。 return preg_replace( '<! - (?!\ s *(?:[if [^ \]] +] | ))(?:(?! - >) 。)* - > '、' '、$ buffer);これは正しいです? – Ian

+1

いいえ、そうではありません。あなたはpreg_replace上のドキュメントを読むべきです。 :-) – Tomalak

+0

私はpreg_replaceに出くわしていないことを認めなければなりません。だから私はチャンスを取るとすぐにドキュメントを読むことを決めます。しかし、この特定の問題の目的のために、それを実装する方法について少し詳しく説明することは可能でしょうか?正規表現よりも広範囲に見えますが、私が試してみたい面白いアプローチのように思えます。 – Ian

0

何かがうまくいくかもしれない乾杯:

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

それは股関節を除いて、あなたと同じですコメントを無視しても、コメント開始タグの直後にカッコがあります。

+0

こんにちは。このメソッドはコメントを削除しますが、<>はスタイルシートが適用されていないことを意味し、ドキュメントは矢印で囲まれています。 – Ian

+0

あなたはこれをこのように呼びますか? (このコードがコメントに投稿されるかどうかわからない) preg_replace( '/ <! - [^ \ [](。| \ s)*? - >、' '、$ buffer); – Boden

+0

開始文字と終了文字を含めるように回答を修正します... – Boden

0

PHPの正規表現エンジンは、次のことを好きですが、このパターンをしようとしますならば、私はよく分からない:

'/<!--(.|\s)*(\[if .*\]){0}(.|\s)*?-->/' 
+0

私の正規表現をこれに置き換えると、それをレンダリングするのではなく、index.phpページのダウンロード保存ポップアップが表示されます。 ? – Ian

1

あなたはそれが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(); ?> 
+0

私は右のスクリプトは次のように頭の中に挿入されなければならない思考でアム: /U'、 'comment_replace_func'、$バッファ); \t関数comment_replace_func($ m){ \t if(preg_match( '/^\ <\! - \ [if \!/ i '、$ m [0])){ \t return $ m [0]; \t} \t返信 ''; \t} ob_start( "callback"); ?> ... HTMLソースはここに... <?php ob_end_flush(); ?> もしそうなら、これでコメントが削除されたり効果があると思われますか? – Ian

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

問題の原因となります。

誰でもこれを考慮に入れて正規表現を提案し、その条件をそのまま残すことができれば完璧です。

トマラックの解はうまく見えますが、初心者でもそれ以上のガイドラインはありません。どのように実装するのかわかりませんが、誰かがそれを適用する方法を詳しく説明できたら、試してみたいですか?

ありがとう

関連する問題