除了第一个之外,从列表中删除所有html标记

时间:2015-08-24 14:09:47

标签: javascript

我有一些html标签和一系列禁止标签: 应该从str中删除在forbiddenTags中找到的任何标记,但第一个标记除外。

也许可以通过字符串的一个循环来完成

我尝试了下一件事:

var forbiddenTags = ["div", "city"];

var str = '<?xml version="1.0" encoding="UTF-8"?>' +
            '<ADDUMP>' +
            '    <HEADER>' +
            '        <div></div>' +
            '        <div>Help Wanted Line</div>' +
            '    </HEADER>' +
            '    <ADINFO>' +
            '        <CUSTOMER>' +
            '            <CITY></CITY>' +
            '            <Div></DIV>' +
            '            <STATE></STATE>' +
            '       </CUSTOMER>' +
            '   </ADINFO>' +
            '</ADDUMP>' +
            '</xml>';

var arrayLength = forbiddenTags.length;

for (var i = 0; i < arrayLength; i++) {
    // remove all forbiddenTags (upper and lower case)
    var re = new RegExp("</? *" + forbiddenTags[i] + "[^>]*>","gi");
    str = str.replace(re, "");
}

console.log(str);

不幸的是,有两个问题:

1)它还删除了在forbiddenTags中找到的字符串的第一个标记。

2)它不会删除标签的内容。

示例:

<div>hi</div>
<div>how</div>
<div></div>

应该是:

<div>hi</div>

这是我的jsfiddle: http://jsfiddle.net/Ht6Ym/3469/

任何帮助表示赞赏!

3 个答案:

答案 0 :(得分:1)

使用str.match获取所有匹配项并弃掉除第一项之外的所有匹配项。

答案 1 :(得分:1)

要匹配标记的内容以及标记本身,您需要更改正则表达式以同时查找开始标记和结束标记。目前,它只检查一个或另一个,这就是留下标签内容的原因。

此正则表达式查找匹配结束标记的开始标记(以及任何关联的属性)以及任何插入文本:

new RegExp("<(" + forbiddenTags[i] + ")[^>]*>(.*?)</\\1>", "gi")

您的其他问题(不想删除第一场比赛)可由passing an anonymous function as a parameter to str.replace解决。在该函数中,使用计数器变量来确定何时删除匹配项。

要做到这一点,你需要在某处添加一个计数器变量。如果您想要保留每种类型的禁止标记的第一个匹配项,请将其放在for循环中。如果您只想保留首先发现的第一个禁止标记,请在for循环之外初始化它(不清楚您想从问题中找到哪个)。然后将str = str.replace(re, "");替换为:

str = str.replace(re, function(matchedText){
    if (++counter>1){
        return "";
    } else {
        return matchedText;
    }
});

此功能针对每场比赛运行。如果它是第一个匹配,它只返回该匹配(实际上,不管它)。否则,它将删除它。

现在,这一切使你的循环看起来像这样:

for (var i = 0; i < forbiddenTags.length; i++) {
    var counter=0
    var re = new RegExp("<(" + forbiddenTags[i] + ")[^>]*>(.*?)</\\1>", "gi");
    str = str.replace(re, function(matchedText){
        if (++counter>1){
            return "";
        } else {
            return matchedText;
        }
    });
}

如果使用jQuery是一个选项,你可以使用this answer中的函数使事情看起来更清晰(即删除令人讨厌的正则表达式):

var removeElements = function(text, selector) {
    var wrapped = $("<div>" + text + "</div>");
    wrapped.find(selector+":not(:first)").remove();
    return wrapped.html();
}

for (var i = 0; i < forbiddenTags.length; i++) {
    str = removeElements(str, forbiddenTags[i]);
}

答案 2 :(得分:0)

似乎Rob W在this post上的回答正是您所寻找的。 您需要更改的是first = truefirst = {}并检查

if (!first[tag]) {
    first[tag] = true;
} else {
    return '';
}