【问题标题】:Whole word regex matching and hyperlinking in JavascriptJavascript中的整个单词正则表达式匹配和超链接
【发布时间】:2020-01-03 15:56:02
【问题描述】:

我需要一些正则表达式方面的帮助。

我正在使用 Javascript 和 JQuery 来超链接 HTML 文档中的术语,为此我使用以下代码。我正在为一个庞大的文档中的多个术语这样做。

var searchterm = "Water";

jQuery('#content p').each(function() {

  var content = jQuery(this),
      txt = content.html(),
      found = content.find(searchterm).length,
      regex = new RegExp('(' + searchterm + ')(?![^(<a.*?>).]*?<\/a>)','gi');

  if (found != -1) {
    //hyperlink the search term
    txt = txt.replace(regex, '<a href="/somelink">$1</a>');
    content.html(txt);
  }
});

然而,有一些我不想匹配的实例,由于时间限制和大脑融化,我正在寻求一些帮助。


编辑:我已经根据@ggorlen 提供的优秀示例更新了下面的代码笔,谢谢!

示例 https://codepen.io/julian-young/pen/KKwyZMr

【问题讨论】:

标签: javascript jquery regex


【解决方案1】:

将整个 DOM 转储为原始文本并使用正则表达式对其进行解析绕过了 jQuery(以及 JS,通过扩展)的主要目的,即将 DOM 作为节点的抽象树进行遍历和操作。

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

获取文本节点后,可以适当地应用正则表达式(解析文本,而不是 HTML)。我使用&lt;mark&gt; 进行演示,但您可以将其设为锚标记或任何您需要的标记。

jQuery 为您提供了一个 replaceWith 方法,该方法在您进行所需的正则表达式替换后替换节点的内容。

$('#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 并应用到文档中的所有内容:

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>

【讨论】:

猜你喜欢
  • 2010-11-15
  • 2012-01-06
  • 1970-01-01
  • 2011-08-07
  • 2017-07-08
相关资源
最近更新 更多