首先,概念证明。查看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 : '');
}
);
请注意,我这样做是为了好玩,而不是因为应该这样解决这个问题。另外,我知道分号捕获很hacky,但这是一种方法。并且可以推断出如何扩展样式的白名单,查看上面的细分。