2015-08-24 58 views
1

我有一串html标记和一个禁止标记列表: 任何在forbiddenTags中找到的标记都应该从str中移除,除了第一个。从字符串除去第一个HTML标记,除第一个以外

也许它可以通过字符串

我试了下事情的一个循环来实现:

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/

任何帮助表示赞赏!

回答

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]); 
} 
0

这似乎是罗布W在this post的答案是你在找什么。 所有你需要改变的是first = truefirst = {}和检查

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

使用str.match让所有的比赛,并放弃所有,除了第一个。

相关问题