0

preg_replace を使用して、HTML サイドワイドのアンパサンドを置き換えようとしていますが、問題は、インライン javascript && または ?page=test&id=1 のような javascript url を壊すことです。

今、私はこのコードを持っています

$amp_replace = array();
$amp_replace[0] = '/(?<=\s)&(?!&)(?!#?[a-z0-9]+;)/';
$amp_replace[1] = '/(?<!&)&(?=\s)/';
$skin = preg_replace($amp_replace, '&amp;', $skin);

左または右にスペースがある場合、アンパサンドを置き換えます。2 つのアンパサンドが連続している場合 (javascript の場合)、または html エンティティが続く場合は置き換えないでください。

しかし、ここではかなり不必要なロジックだと思います。また、test&test のような場合は、アンパサンドを置き換えません。

私は正規表現の専門家ではないので、これにはかなりの時間がかかりました。そのため、ここでもう一度助けを求めることにしました。

JavaScript スクリプト タグ内にない場合は、単にすべてのアンパサンドを置き換える方がよいでしょうか? 私はすでにそれを試しましたが、本当の成功はありません

それをアーカイブする方法を知っている人はいますか?ありがとうございました

4

2 に答える 2

1

コンテンツ内の '&' を変換し、タグ (つまり、属性値)を避け、スクリプト ブロックを避けたいだけの場合は
、以下のようなものがほとんどの場合に機能します。
ただし、属性値も変換する必要があることに注意してください。
そして、それを行うには、さらに多くの作業が必要です。

作業サンプルhttp://www.ideone.com/9MhCq

<?php

$html=<<<EOD
 <some &ta&g> S&P &&more; and &some; <more> &notme;
  && &#209; &#xa92F;
 <script flavor?>
   val && this & this 
 </script>
 &
EOD;

$rxent = '(?:&(?:[A-Za-z_:][\w:.-]*|\#(?:[0-9]+|x[0-9a-fA-F]+));)';

$rxtag =
'<
 (?:
     \?php\s+.*?\?
  |  (?:
       (?:
           (?:script|style)\s*
         | (?:script|style)\s+(?:".*?"|\'.*?\'|[^>]*?)+\s*
       )> .*? </(?:script|style)\s*
     )
  |  (?:
         /?[A-Za-z_:][\w:.-]*\s*/?
       |  [A-Za-z_:][\w:.-]*\s+(?:".*?"|\'.*?\'|[^>]*?)+\s*/?
       | !(?:DOCTYPE.*?|--.*?--)
     )
 )
 >
';

$rxmain = "~(?xs:((?:$rxtag)+) | ((?!$rxent)&))~";


print "$html\n\n";

$html = preg_replace_callback($rxmain, 'fixamp_cb', $html);

print "$html\n";

function fixamp_cb( $matches ) {
    # Return tags and script blocks unchanged.
    if (isset($matches[1]) && $matches[1])
       return $matches[1];
    return '&amp;';
}

?>
于 2011-10-22T00:17:12.930 に答える
0

次のような単純なものではないのはなぜですか:

$html = preg_replace('/([^&])&([^&])/', '$1&amp;$2', $html);

Javascript 内のすべてのアンパサンドを置き換えたくない場合は、スクリプト タグの先読み/後読みを追加するか、最初にスクリプト タグでドキュメントを分割し、非スクリプト部分でのみ置換を実行します。

$html = preg_split('/<\/?script>/', $html);
foreach ($html as $k => $v) {
  if ($piece[0] == "<") {
    $html[$k] = preg_replace('/([^&])&([^&])/', '$1&amp;$2', $v);
  } else {
    $html[$k] = "<script>" . $html[$k] . "</script>";
}

スクリプト タグに属性がある場合は、これを変更する必要があります。

ユーザー コンテンツをサニタイズする場合は、既に利用可能なツールを使用した方がよい場合があります。HTML ピューリファイヤーを参照してください

于 2011-10-21T16:44:23.237 に答える