2015-08-24 94 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讓所有的比賽,並放棄所有,除了第一個。

相關問題