私は perl 正規表現の置換についてはかなりの能力を持っていますが、ちょっと錆びてきており、これは普段はしないことです。XML の & 文字をエスケープするためですが、すでにエスケープされた文字の & を置き換えることはできません。その右側の文字を削除または置換することを除いて、正常に動作するようです。私は何が欠けていますか?
$str =~ s/&[^amp;|lt;|gt;|quot;|#39;]/&/g;
私は perl 正規表現の置換についてはかなりの能力を持っていますが、ちょっと錆びてきており、これは普段はしないことです。XML の & 文字をエスケープするためですが、すでにエスケープされた文字の & を置き換えることはできません。その右側の文字を削除または置換することを除いて、正常に動作するようです。私は何が欠けていますか?
$str =~ s/&[^amp;|lt;|gt;|quot;|#39;]/&/g;
否定された文字クラスを否定的な先読みと間違えています。
あなたの正規表現は本当に意味します:
/&[^#39aglmopqtu;|]/ # mixed a few letters and removed duplicates
しかし、あなたが意味したのは:
/&(?!amp;|lt;|gt;|quot;|#39;)/
角かっこは、グループ化ではなく、文字クラスを表します!
XMLエンティティの一致を本当に避けたい場合は、次のような正規表現を使用する必要があります
m{& (?! (?:
(?:\#[0-9]+)
|(?:\#x[0-9a-fA-F]+)
|(?:[lg]t|amp|apos|quot) # predefined XML entities
); )}x
( XML 仕様を比較してください) 何らかの方法で、ドキュメントによって宣言されているすべてのエンティティ、または参照されている DTD を追加します。
ゼロ幅の負の先読みが必要なようです。何かのようなもの
$str =~ s/&(?!amp;|lt;|gt;|quot;|#39;)/&/g;