目標は次のとおりです。すべてのスタンドアロンのアンパサンドを & に置き換えることです。ただし、 などの HTML エンティティの一部になっているものは置き換えないでください。
スタンドアロンのアンパサンドのみに一致する PHP (できれば preg_ 関数) の正規表現が必要だと思います。preg_replace でそれを行う方法がわかりません。
PHPにhtmlentities()
はdouble_encode
これに対する引数があります。
正規表現でそのようなことをしたい場合は、否定的なアサーションが役に立ちます:
preg_replace('/&(?!(?:[[:alpha:]][[:alnum:]]*|#(?:[[:digit:]]+|[Xx][[:xdigit:]]+));)/', '&', $txt);
html_entity_decode
走る前にいつでも走れますhtmlentities
か?アンパサンドのみを実行したい場合を除き、機能します (その場合でも、文字セット パラメータを操作できます)。
正規表現よりもはるかに簡単で高速です。
ロスは私に良い答えを導きました。これはかなりうまくいくと思われるコードです。ここのところ。:-) 繰り返しますが、目標は HTML を XML に変換することです。具体的には、RSS フィードの説明です。私がこれまでに行った簡単なテスト (いくつかのかなり風変わりなデータを使用) では、CDATA でラップされた文字列を取得してラップを解除することができました。検証テストに合格します。ありがとう、ロス。
//decode all entities
$string=html_entity_decode($string,ENT_COMPAT,'UTF-8');
//entity-encode only &<> and double quotes
$string=htmlspecialchars($string,ENT_COMPAT,'UTF-8');
他のものは良い提案であり、それを行うためのより良い方法かもしれません. しかし、正規表現の例を提供するためだけに、質問に答えようと思いました。
以下は、一部のエンジンで許可されている特別な分解形式です。もちろん、奇妙なことに、コメント付きの正規表現を許可するエンジンは、他の簡略化された式を許可しますが、一般的なものではありません。これらの簡略化された表現は、コメントの括弧内に入れます。
& # an ampersand
( \# # a '#' character
[1-9] # followed by a non-zero digit,
[0-9]{1,3} # with between 2 and 4 (\d{1,3} or \p{IsDigit}{1,3})
| [A-Za-z] # OR a letter (\p{IsAlpha})
[0-9A-Za-z]+ # followed by letters or numbers (\p{IsAlnum}+)
)
; # all capped with a ';'
正規表現スキャナーを支援するために、そこに予想されるエンティティの束を投げることさえできます。
& # an ampersand
( amp | apos | gt | lt | nbsp | quot
# standard entities
| bull | hellip | [lr][ds]quo | [mn]dash | permil
# some fancier ones
| \# # a '#' character
[1-9] # followed by a non-zero digit,
[0-9]{1,3} # with between 2 and 4
| [A-Za-z] # OR a letter
[0-9A-Za-z]+ # followed by letters or numbers
)
; # all capped with a ';'
私は同じ問題を抱えていましたが、もともとは次のものを使用していました:
$string = htmlspecialchars($string, ENT_QUOTES, "UTF-8", FALSE);
しかし、PHP4とCharSetの組み合わせで動作する必要があり、最終的には次のようになりました。
function htmlspecialchars_custom($string)
{
$string = str_replace("\x05\x06", "", $string);
$string = preg_replace("/&([a-z\d]{2,7}|#\d{2,5});/i", "\x05\x06$1", $string);
$string = htmlspecialchars($string, ENT_QUOTES);
$string = str_replace("\x05\x06", "&", $string);
return $string;
}
完璧ではありませんが、私のニーズには十分です。