-1

i have code below which finds and wraps those words in a span element, but only them. i would like to wrap a whole word if it inludes those words. for example: GSHAA or GSH112

my code:

var words = ["GSHT","GSH","SHV"];

$('.list-icons a').html(function(_,html) {
    var reg = new RegExp('('+words.join('|')+')','gi');
    return html.replace(reg, '<span class="wrap">$1</span>', html)
});
Gallex
  • 311
  • 3
  • 8
  • 18
  • remove that `$1`, as not everyone understands PHP syntax in that case – Flash Thunder Jan 11 '21 at 13:18
  • @FlashThunder in a js regex replace operation `$1` gets replaced by the first capture group and so is not PHP. I understand the confusion though as that syntax is pretty much forever imprinted into my brain as well. – soimon Jan 11 '21 at 13:35

2 Answers2

0

In order for your regular expression to match the entire word instead of only the substring, you should check for the word boundary using \b. See this solution:

var words = ["a", "b", "c"];

// To prevent errors when looking for words with special characters
const escapeRegex = (str) => str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');

$('.list-icons a').html(function(_, html) {
  const query = words.map(escapeRegex).join('|');
  const regex = new RegExp(`(\\b\\w*(?:${query})\\w*\\b)`, 'gi');
  return html.replace(regex, '<span class="wrap">$1</span>')
});
.wrap {
  background: black;
  color: white
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="list-icons">
  <li><a>Apple pie ice</a></li>
  <li><a>Blueberry cake</a></li>
  <li><a>Honey</a></li>
</ul>

Simplified, (\\b\\w*word\\w*\\b) means "look for a string that begins with a word boundary (a space or a newline), then your word followed and preceded by any amount of alphanumeric characters (\w*) and ends with a word boundary again".

Because you are inserting your words into a regular expression, you should escape them so that special characters (like $ . and +) do not cause regex parsing errors. I took and modified escapeRegex from this answer.

soimon
  • 2,400
  • 1
  • 15
  • 16
-1

according to the docs, you must return the changed value of the HTML not to use the HTML replace function

var words = ["GSHT","GSH","SHV"];

console.log($('.list-icons a')[0]);

$('.list-icons a').html(function(_,tag) {
    var reg = new RegExp('('+words.join('|')+')','gi');
    if(reg.test(tag)){
      return `<span class="wrap">${tag}</span>`
    }
});

console.log($('.list-icons a span')[0]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="list-icons">
  <li><a>GSHAA</a></li>
   <li><a>a</a></li>
  <li><a>a</a></li>
</ul>
Ahmed Gaafer
  • 1,603
  • 9
  • 26