【问题标题】:Stripping HTML Down To Allowed Tags将 HTML 剥离为允许的标签
【发布时间】:2017-04-29 20:09:11
【问题描述】:

我想去除所有 HTML 标记(但不包括内容),列表中给出的标记除外。

我想用 Node 来做这个。

以下正则表达式可以匹配标签<[a|br].+?>|<\/[a]>,但是我怎样才能继续删除除了匹配的标签之外的所有标签?

【问题讨论】:

    标签: javascript node.js regex


    【解决方案1】:

    仅替换 abr

    1. [] 集合中没有 |[a|br] 的集合是:a|br。请改用非捕获组。
    2. .+? 应该是 .*? 以替换 <a><br>
    3. 集合[a] 可能只是a

    试试这个:

    /<(?:a|br).*?>|<\/a>/g
    

    https://regex101.com/r/KWJi01/2

    替换除abr 之外的所有标签:

    使用这个正则表达式:

    /<(?:(?!\/?a|br).*?)>/g
    

    https://regex101.com/r/KWJi01/3

    【讨论】:

    • 啊。这目前匹配所有列出的标签 - 是否可以使其匹配所有标签 除了 列出的标签(以便我可以删除它们)?
    【解决方案2】:

    不使用正则表达式的问题的另一种解决方案是以下方法:

    // creating a function which takes two arguments:
    // htmlString: String, a string of HTML to process,
    // permitted:  Array, an array of HTML element tag-names.
    function filterHTML(htmlString, permitted) {
    
      // here we iterate over the Array of permitted elements,
      // and convert any uppercase tag-names to lowercase:
      permitted = permitted.map(
        el => el.toLowerCase()
      );
    
      // creating a new element in which to hold the passed-in
      // string of HTML when parsed into HTML:
      let temp = document.createElement('div');
    
      // assigning the passed-in string of HTML as the
      // innerHTML of the temp element:
      temp.innerHTML = htmlString;
    
      // finding all elements held within the temp element,
      // and passing the NodeList to Array.from() in order
      // to convert the Array-like NodeList into an Array:
      let allElements = Array.from(temp.querySelectorAll('*'));
    
      // iterating over the array of found elements, using
      // Array.prototype.forEach():
      allElements.forEach(
    
        // using an Arrow function, 'element' is the current
        // element of the Array of elements over which we're
        // iterating:
        element => {
    
          // if the current element's tagName - converted to
          // lowercase - is not found within the Array of
          // permitted tags:
          if (permitted.indexOf(element.tagName.toLowerCase()) === -1) {
    
            // while the current (unpermitted) element has
            // a first-child:
            while (element.firstChild) {
    
              // we access the element's parent node, and
              // call node.insertBefore() to place the
              // first-child of the element before the
              // element (removing it from the element
              // which is unpermitted and placing it as
              // a previous-sibling):
              element.parentNode.insertBefore(element.firstChild, element);
            }
    
            // finding the element's parent node, and calling
            // node.removeChild() in order to remove the current
            // element from its parent node (and therefore from
            // the temp element):
            element.parentNode.removeChild(element);
          }
        });
    
      // here we return the innerHTML of the temp element, after
      // all unpermitted elements have been removed:
      return temp.innerHTML;
    }
    
    // the allowed tags, to be used in the above function,
    // note that the tags do not have the '<', '>' or any
    // attributes:
    let allowedTags = ['br', 'div'];
    
    // the following is just to visually display on the page
    // the unprocessed and processed innerHTML, and also the
    // rendered HTML following the processing:
    document.querySelector('#input').textContent = document.querySelector('#test').innerHTML;
    
    document.querySelector('#output').textContent = filterHTML(document.querySelector('#test').innerHTML, allowedTags).trim();
    
    document.querySelector('#result').innerHTML = document.querySelector('#output').textContent;
    

    function filterHTML(htmlString, permitted) {
      let temp = document.createElement('div');
    
      temp.innerHTML = htmlString;
    
      let allElements = Array.from(temp.querySelectorAll('*'));
    
      allElements.forEach(
        element => {
          if (permitted.indexOf(element.tagName.toLowerCase()) === -1) {
            while (element.firstChild) {
              element.parentNode.insertBefore(element.firstChild, element);
            }
            element.parentNode.removeChild(element);
          }
        });
      return temp.innerHTML;
    }
    
    let allowedTags = ['br', 'div'];
    
    document.querySelector('#input').textContent = document.querySelector('#test').innerHTML;
    
    document.querySelector('#output').textContent = filterHTML(document.querySelector('#test').innerHTML, allowedTags).trim();
    
    document.querySelector('#result').innerHTML = document.querySelector('#output').textContent;
    div {
      border: 2px solid #000;
      margin: 0 0 1em 0;
      padding: 0.5em;
      box-sizing: border-box;
      border-radius: 1em;
    }
    
    div[id$=put] {
      white-space: pre-wrap;
    }
    
    #input {
      border-color: #f00;
    }
    
    #output {
      border-color: limegreen;
    }
    
    ::before {
      color: #666;
      display: block;
      border-bottom: 1px solid #666;
      margin-bottom: 0.5em;
    }
    
    #input::before {
      content: 'The original innerHTML of the "#test" element:';
    }
    
    #output::before {
      content: 'The filtered innerHTML, with only permitted elements remaining:'
    }
    
    #result::before {
      content: 'This element shows the filtered HTML of the "test" element:'
    }
    <div id="test">
      <div><span>
          <a href="#">link text!</a>
          <br />
          <hr />
          <div>div text!</div>
        </span></div>
    </div>
    
    <div id="input"></div>
    <div id="output"></div>
    <div id="result"></div>

    JS Fiddle demo.

    参考资料:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-14
      • 2013-07-11
      • 1970-01-01
      • 2016-08-03
      • 1970-01-01
      • 2014-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多