Javascript中的整个单词正则表达式匹配和超链接 [英] Whole word regex matching and hyperlinking in Javascript

查看:63
本文介绍了Javascript中的整个单词正则表达式匹配和超链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一些有关正则表达式的帮助.

I need a little help with Regular Expressions.

我正在使用Javascript和JQuery来超链接HTML文档中的术语,为此,我正在使用以下代码.我要在大量文档中使用多个术语来完成此操作.

I'm using Javascript and JQuery to hyperlink terms within an HTML document, to do this I'm using the following code. I'm doing this for a number of terms in a massive document.

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);
  }
});

但是,我不想匹配很多实例,由于时间限制和大脑融化,我正在寻求帮助.

There are however a number of instances I do not want to match and due to time constraints and brain melt, I'm reaching out for some assistance.

我已经根据@ggorlen提供的出色示例更新了以下代码库,谢谢!

I've updated the codepen below based on the excellent example provided by @ggorlen, thank you!

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

推荐答案

将整个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>

这篇关于Javascript中的整个单词正则表达式匹配和超链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆