まず、概念実証。Rubular のデモをご覧ください。
正規表現は次のようになります。
/(<[^>]+\s+)(?:style\s*=\s*"(?!(?:|[^"]*[;\s])color\s*:[^";]*)(?!(?:|[^"]*[;\s])background-color\s*:[^";]*)[^"]*"|(style\s*=\s*")(?=(?:|[^"]*[;\s])(color\s*:[^";]*))?(?=(?:|[^"]*)(;))?(?=(?:|[^"]*[;\s])(background-color\s*:[^";]*))?[^"]*("))/i
分解すると、次のようになります。
(<[^>]+\s+) Capture start tag to style attr ($1).
(?: CASE 1:
style\s*=\s*" Match style attribute.
(?! Negative lookahead assertion, meaning:
(?:|[^"]*[;\s]) If color found, go to CASE 2.
color\s*:[^";]*
)
(?!
(?:|[^"]*[;\s]) Negative lookahead assertion, meaning:
background-color\s*:[^";]* If background-color found, go to CASE 2.
)
[^"]*" Match the rest of the attribute.
| CASE 2:
(style\s*=\s*") Capture style attribute ($2).
(?= Positive lookahead.
(?:|[^"]*[;\s])
(color\s*:[^";]*) Capture color style ($3),
)? if it exists.
(?= Positive lookahead.
(?:|[^"]*)
(;) Capture semicolon ($4),
)? if it exists.
(?= Positive lookahead.
(?:|[^"]*[;\s])
(background-color\s*:[^";]*) Capture background-color style ($5),
)? if it exists.
[^"]*(") Match the rest of the attribute,
capturing the end-quote ($6).
)
さて、交換品ですが、
\1\2\3\4\5\6
残っていると予想されるものを常に構築する必要があります。
ここでの秘訣は、明確でない場合に備えて、「負の」ケースを最初に配置することです。これにより、負のケースが失敗した場合にのみ、キャプチャ (スタイル属性自体など) が、もちろん代替によって取り込まれます。場合。それ以外の場合、キャプチャはデフォルトで何も表示されないため、スタイル属性も表示されません。
JavaScript でこれを行うには、次のようにします。
htmlString = htmlString.replace(
/(<[^>]+\s+)(?:style\s*=\s*"(?!(?:|[^"]*[;\s])color\s*:[^";]*)(?!(?:|[^"]*[;\s])background-color\s*:[^";]*)[^"]*"|(style\s*=\s*")(?=(?:|[^"]*[;\s])(color\s*:[^";]*))?(?=(?:|[^"]*)(;))?(?=(?:|[^"]*[;\s])(background-color\s*:[^";]*))?[^"]*("))/gi,
function (match, $1, $2, $3, $4, $5, $6, offset, string) {
return $1 + ($2 ? $2 : '') + ($3 ? $3 + ';' : '')
+ ($5 ? $5 + ';' : '') + ($2 ? $6 : '');
}
);
これがこの問題を解決する方法であるからではなく、楽しみのためにこれを行っていることに注意してください。また、セミコロン キャプチャがハックであることは承知していますが、これは 1 つの方法です。上記の内訳を見ると、スタイルのホワイトリストを拡張する方法を推測できます。