且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Javascript中的整个单词正则表达式匹配和超链接

更新时间:2023-02-23 13:47:11

将整个DOM转储为原始文本并使用regex对其进行解析,从而规避了jQuery(和扩展名JS)的主要目的,即遍历和操纵jQuery.DOM作为节点的抽象树.

Dumping the entire DOM to raw text and parsing it with regex circumvents the primary purpose of jQuery (and JS, by extension), which is to traverse and manipulate the DOM as an abstract tree of nodes.

文本节点具有 nodeType Node.TEXT_NODE ,我们可以在遍历中使用它来识别您感兴趣的非链接节点.

Text nodes have a nodeType Node.TEXT_NODE which we can use in a traversal to identify the non-link nodes you're interested in.

获取文本节点后,可以适当地应用正则表达式(解析文本,而不是HTML).我出于演示目的使用< mark> ,但是您可以将其设为定位标记或任何您需要的标记.

After obtaining a text node, regex can be applied appropriately (parsing text, not HTML). I used <mark> for demonstration purposes, but you can make this an anchor tag or whatever you need.

jQuery为您提供了一个 replaceWith 方法,该方法替换了完成所需的正则表达式替换后的节点.

jQuery gives you a replaceWith method that replaces the content of a node after you've made the desired regex substitution.

$('#content li').contents().each(function () {
  if (this.nodeType === Node.TEXT_NODE) {    
    var pattern = /(\b[Ww]aters?(?!-)\b)/g;
    var replacement = '<mark>$1</mark>';
    $(this).replaceWith(this.nodeValue.replace(pattern, replacement));
  }
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>Example Content</h1>
<div id="content">
  <ul>
    <li>Water is a fascinating subject. - <strong>match</strong></li>
    <li>We all love water. - <strong>match</strong></li>
    <li>ice; water; steam - <strong>match</strong></li>
    <li>The beautiful waters of the world - <strong>match</strong> (including the s)</li>
    <li>and all other water-related subjects - <strong>no match</strong></li>
    <li>and this watery topic of - <strong>no match</strong></li>
    <li>of WaterStewardship looks at how best - <strong>no match</strong></li>
    <li>On the topic of <a href="/governance">water governance</a> - <strong>no match</strong></li>
    <li>and other <a href="/water">water</a> related things - <strong>no match</strong></li>
    <li>the best of <a href="/allthingswater">all things water</a> - <strong>no match</strong></li>
  </ul>
</div>

您可以在没有jQ的情况下执行此操作,并将其应用于文档中的所有内容:

You can do it without jQ and apply to everything in the document:

for (const parent of document.querySelectorAll("body *:not(a)")) {
  for (const child of parent.childNodes) {
    if (child.nodeType === Node.TEXT_NODE) {
      const pattern = /(\b[Ww]aters?(?!-)\b)/g;
      const replacement = "<mark>$1</mark>";
      const subNode = document.createElement("span");
      subNode.innerHTML = child.textContent.replace(pattern, replacement);
      parent.insertBefore(subNode, child);
      parent.removeChild(child);
    }    
  }
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  hello water
  <div>
    <div>
      I love Water.
      <a href="">more water</a>
    </div>
    watership down
    <h4>watery water</h4>
    <p>
      waters
    </p>
    foobar <a href="">water</a> water
  </div>
</div>