Javascript 删除 html 内容中的 \n 或 \t,pre 标签除外

Javascript remove \n or \t in html content except within pre tags

在 Javascript 中,如何删除 html 字符串中的换行符(\n 或 \t),但 <pre> 标签内除外。

我使用此代码删除换行符:

htmlString.replace(/[\n\t]+/g,"");

但是,它还会删除 <pre> 标签中的 \n\t。如何解决?

您可以使用 TreeWalker in order to select all text nodes 并将正则表达式仅应用于这些节点:

//
// closest Polyfill from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
//
if (window.Element && !Element.prototype.closest) {
  Element.prototype.closest = function (s) {
      var matches = (this.document || this.ownerDocument).querySelectorAll(s), i, el = this;
      do {
          i = matches.length;
          while (--i >= 0 && matches.item(i) !== el) {
          };
      } while ((i < 0) && (el = el.parentElement));
      return el;
  };
}


document.getElementById("remove").addEventListener('click',  function(e) {
    //
    // traverse the DOM
    //
    var walker = document.createTreeWalker(
            document.body,
            NodeFilter.SHOW_TEXT,
            null,
            false
    );

    var node;
    while (node = walker.nextNode()) {
        if (node.parentElement.closest('PRE') != null) {
            node.textContent = node.textContent.replace(/[\n\t]+/g, "");
        }
    }
});
pre {
    background: #fffbec;
}
<button id="remove">Remove</button><br>



<pre>
    this is a pre tag

    with    tab
</pre>

<pre class="language-cpp">
  <code>
    void main() {
      printf("Hello");
    }
  </code>
</pre>

<p>
    first word

    new       end</p>

可以先匹配需要清理的文字,只能是:

  • 从字符串开头到下一个开始 <pre> 标记的文本。
  • 从结束 </pre> 标签到下一个开始 <pre> 标签的文本。
  • 从结束 </pre> 标记到字符串末尾的文本。
  • 从字符串开头到字符串结尾的文本(字符串中没有 pre 个元素)。

可以用正则表达式描述为:

(?:^|<\/pre>)[^]*?(?:<pre>|$)/g

其中 [^] 匹配任何内容,包括新行,*? 是一个非贪婪量词,以尽可能少地匹配。


接下来,我们得到需要清洗的匹配文本,所以我们使用正则表达式/[\n\t]+/g清洗它。


示例:

var htmlString = "<body>\n\t<p>\n\t\tLorem\tEpsum\n\t</p>\n\t<pre>\n\t\tHello, World!\n\t</pre>\n\n\t<pre>\n\t\tThis\n\t\tis\n\t\tawesome\n\t</pre>\n\n\n</body>";

var preview = document.getElementById("preview");
preview.textContent = htmlString;

document.getElementById("remove").onclick = function() {
    preview.textContent = htmlString.replace(/(?:^|<\/pre>)[^]*?(?:<pre>|$)/g, function(m) {
        return m.replace(/[\n\t]+/g, "");
    });
}
pre {
    background: #fffbec;
}
<button id="remove">Remove</button>
The pre bellow is just used to show the string, it is not THE PRE.
<pre id="preview"></pre>


Regex101 Example.