【问题标题】:RegEx to remove all styles but leave color and background-color if they existRegEx 删除所有样式,但保留颜色和背景颜色(如果存在)
【发布时间】:2012-09-13 18:18:25
【问题描述】:

我仍然无法使用正则表达式,因此无法找到最终解决方案来使用带有 Javascript 的 RegEx 从

...

中删除所有样式,但是 保留颜色和背景颜色(如果存在)

我发现了什么:

1.使用正则表达式删除完整的 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>

【问题讨论】:

  • 不要使用正则表达式解析或修改 HTML。结局不会很好。
  • 我知道这个讨论谢谢 :) 就我而言,使用 RegEx 很好。
  • 它不是,它永远不会很好,它充其量是可行unless you are a devil worshipping, virgin-blood drinking wonderpony,请改正你的方式......请
  • “不管我们说多少次,他们每天都不会停止......” +1 --- 但是,我上面的例子可以用于其他场景(XML),并且不能绑定到 HTML ;)
  • 我假设您事先不知道样式属性出现的顺序,对吧?因为真的,在那种情况下,你不会用正则表达式得到满意的解决方案。

标签: javascript regex


【解决方案1】:

首先,概念证明。查看the Rubular demo

正则表达式是这样的:

/(<[^>]+\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,但这是一种方法。通过查看上面的细分,我们可以推断出如何扩展样式白名单。

【讨论】:

  • +1。哎呀。好的,所以从技术上讲,它不是一个纯粹的正则表达式替换,因为您需要额外的程序逻辑来选择替换,但是纯粹的正则表达式勇敢!
  • @TimPietzcker - 好吧,只有 JavaScript,(1)使用反向引用需要调用一个函数,(2)未捕获的组不默认为空字符串,所以你可以不只是将它们全部连接起来。但是,是的,我可以看到我的声明可能是如何误导的!
  • 很好的答案,很高兴你也解释了这些部分!我在问题的两个示例中都使用了您的 javascript 代码,但是,第一个示例变为:

    example

    而不是

    示例

    ?
  • 你确定吗?这个对我有用。这是jsFiddle
  • 我刚刚意识到它可以在我的工作计算机(运行 Internet Explorer 8)上运行,但不能在其他浏览器上运行!难怪你说它不起作用。我得回家再看一遍。
【解决方案2】:

您可以通过使用此功能在不使用正则表达式的情况下完成此操作

function filter_inline_style(text){
    var temp_el = document.createElement("DIV");
    temp_el.innerHTML = text;
    var el            = temp_el.firstChild;
    console.log("el", el);

    // Check if text contain html tags
    if(el.nodeType == 1){
        var background = el.style.backgroundColor;
        var color      = el.style.color;

        el.removeAttribute('style');
        el.style.backgroundColor = background;
        el.style.color           = color;
        return el.outerHTML
    }

    return temp_el.innerHTML;
}

使用它:

var text = '<p style="font-size:8px;line-height:14px;color:#FF0000;background-color: red">example</p>';
var clean_text = filter_inline_style(text);
console.log(clean_text); 
// output: <p style="background-color: red; color: rgb(255, 0, 0);">example</p>

【讨论】:

    猜你喜欢
    • 2020-01-11
    • 2014-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多