2015-08-24 2 views
1

У меня есть строка тегов html и список запрещенных тегов: Любой тег, который находится в запрещенных тегах, должен быть удален из 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) Он удаляет также первый тег строки, который находится в запрещенных тагах.

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

Кажется, ответ Роб У на this post - это то, что вы ищете. Все, что вам нужно изменить это first = true к first = {} и проверить

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

Используйте str.match, чтобы получить все матчи и отбросить все за исключением первого.

Смежные вопросы