4

我仍然无法使用正则表达式,因此无法找到最终解决方案来使用带有 Javascript 的 RegEx 从 <p style="">...</p> 中去除所有样式,但保留颜色和背景-如果它们存在,则为颜色

我发现了什么:

1. 使用 RegEx 删除完整的 style="..." 元素:

htmlString = (htmlString).replace(/(<[^>]+) style=".*?"/i, '');


2. 使用 RegEx 删除某些样式:

htmlString = (htmlString).replace(/font-family\:[^;]+;?|font-size\:[^;]+;?|line-height\:[^;]+;?/g, '');


挑战:如果我们删除了所有分配的样式(不存在颜色),并且样式为空(我们有 style="" 或 style=" "),那么 style 属性也应该被删除。

我想我们需要两行代码?

任何帮助表示赞赏!


示例 1(列入白名单的“颜色”仍然存在):

<p style="font-family:Garamond;font-size:8px;line-height:14px;color:#FF0000;">example</p>

应该变成:

<p style="color:#FF0000;">example</p>


示例 2(所有样式都死了):

<p style="font-family:Garamond;font-size:8px;line-height:14px;">example</p>

应该变成:

<p>example</p>
4

1 回答 1

3

首先,概念证明。查看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,但这是一种方法。并且可以推断出如何扩展样式的白名单,查看上面的细分。

于 2012-09-13T21:27:42.343 回答