使用JavaScript正则表达式从HTML标记中删除不必要的属性

3

我是一个正则表达式的新手,试图过滤HTML标签并只保留必需的(src/href/style)属性及其值,并删除不必要的属性。当我在谷歌上搜索时,我找到了一个仅保留"src"属性的正则表达式,因此我的修改后的表达式如下:

<([a-z][a-z0-9]*)(?:[^>]*(\s(src|href|style)=['\"][^'\"]*['\"]))?[^>]*?(\/?)>

它的工作正常,但唯一的问题是,如果一个标签包含多个必需属性,则仅保留最后匹配的单个属性并丢弃其余属性。

我正在尝试清理以下文本

<title>Hello World</title>
<div fadeout"="" style="margin:0px;" class="xyz">
    <img src="abc.jpg" alt="" />
    <p style="margin-bottom:10px;">
        The event is celebrating its 50th anniversary K&ouml;&nbsp;
        <a style="margin:0px;" href="http://www.germany.travel/">exhibition grounds in Cologne</a>.
    </p>
    <p style="padding:0px;"></p>
    <p style="color:black;">
        <strong>A festival for art lovers</strong>
    </p>
</div>

使用上述表达式,在https://regex101.com/#javascript 上,将<$1$2$4>作为替换字符串,得到以下输出:

<title>Hello World</title>
<div style="margin:0px;">
    <img src="abc.jpg"/>
    <p style="margin-bottom:10px;">
        The event is celebrating its 50th anniversary K&ouml;&nbsp;
        <a href="http://www.germany.travel/">exhibition grounds in Cologne</a>.
    </p>
    <p style="padding:0px;"></p>
    <p style="color:black;">
        <strong>A festival for art lovers</strong>
    </p>
</div>

问题是锚点标签中的“style”属性被丢弃了。我尝试使用*运算符、{3}选择器等来复制(\s(src|href|style)=['\"][^'\"]*['\"])块,但都无济于事。有什么建议吗?


我建议使用RegexBuddy来测试表达式。它曾经为我节省了很多时间。https://www.regexbuddy.com/ - Bozidar Sikanjic
参考代码可以在 https://regex101.com/r/mP0pX6/1 找到。 - Adrian Wragg
1
为什么不使用DOM操作而使用RegEX? - Salman A
1
@SalmanA 我正在尝试使用DOM操作来实现相同的功能,但是jquery 1.9.1失败了。jQuery 2.0.0修复了这个问题,但我的应用程序中其他库不兼容。有什么建议吗?这是我的fiddler测试链接:https://jsfiddle.net/vytu9duc/5/控制台显示以下错误:Uncaught InvalidCharacterError: Failed to execute 'setAttribute' on 'Element': 'fadeout"' is not a valid attribute name.有什么建议吗? - Ahmad Ahsan
2个回答

5

@AhmadAhsan,这里是使用DOM操纵解决您问题的演示:https://jsfiddle.net/pu1hsdgn/

   <script src="https://code.jquery.com/jquery-1.9.1.js"></script>
    <script>
        var whitelist = ["src", "href", "style"];
        $( document ).ready(function() {
            function foo(contents) {
            var temp = document.createElement('div');
            var html = $.parseHTML(contents);
            temp = $(temp).html(contents);

            $(temp).find('*').each(function (j) {
                var attributes = this.attributes;
                var i = attributes.length;
                while( i-- ) {
                    var attr = attributes[i];
                    if( $.inArray(attr.name,whitelist) == -1 )
                        this.removeAttributeNode(attr);
                }
            });
            return $(temp).html();
        }
        var raw = '<title>Hello World</title><div style="margin:0px;" fadeout"="" class="xyz"><img src="abc.jpg" alt="" /><p style="margin-bottom:10px;">The event is celebrating its 50th anniversary K&ouml;&nbsp;<a href="http://www.germany.travel/" style="margin:0px;">exhibition grounds in Cologne</a>.</p><p style="padding:0px;"></p><p style="color:black;"><strong>A festival for art lovers</strong></p></div>'
        alert(foo(raw));
    });
    </script>

1

这是根据您原始的正则表达式:

<([a-z][a-z0-9]*?)(?:[^>]*?((?:\s(?:src|href|style)=['\"][^'\"]*['\"]){0,3}))[^>]*?(\/?)>

第一组是标签名,第二组是属性,第三组是/(如果有的话)。我无法使其与不允许的属性交替使用的允许属性一起工作,例如:<a href="foo" class="bar" src="baz" />。我认为这是不可能的。

编辑:根据@AhmadAhsan的更正,正则表达式应该是:

var html = `<div fadeout"="" style="margin:0px;" class="xyz">
                <img src="abc.jpg" alt="" />
                <p style="margin-bottom:10px;">
                    The event is celebrating its 50th anniversary K&ouml;&nbsp;
                    <a style="margin:0px;" href="http://www.germany.travel/">exhibition grounds in Cologne</a>.
                </p>
                <p style="padding:0px;"></p>
                <p style="color:black;">
                    <strong>A festival for art lovers</strong>
                </p>
            </div>`


console.log( 
  html.replace(/<([a-z][a-z0-9]*)(?:[^>]*?((?:\s(?:src|href|style)=['\"][^'\"]*['\"]){0,3}))[^>]‌​*?(\/?)>/, '')
)
    


1
与其使用懒惰搜索“?”来搜索标记名称,不如使用贪婪“”,否则只会返回“t”,而不是“title”。 使用子字符串<$1$2$3>:<([a-z][a-z0-9])(?:[^>]?((?:\s(?:src|href|style)=['"][^'"]['"]){0,3}))[^>]?(/?)>虽然它不能满足我的要求,但对其他人可能有帮助。 - Ahmad Ahsan
@AhmadAhsan 你说得对。我只在一个 a 标签上测试了它。 - Joels Elf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接