Find a string of text in an element and wrap some span tags round it

JqueryStringText

Jquery Problem Overview


I want to find a string of text in an element and wrap some span tags round it. E.g.

From:

<h2>We have cows on our farm</h2>

To:

<h2>We have <span class='smallcaps'>cows</span> on our farm</h2>

I've tried:

$("h2:contains('cow')").each(function() {
 $(this).text().wrap("<span class='smallcaps'></span>");
});

But that only wraps the whole containing h2 tag.

Jquery Solutions


Solution 1 - Jquery

$("h2:contains('cow')").html(function(_, html) {
   return html.replace(/(cow)/g, '<span class="smallcaps">$1</span>');
});

http://jsfiddle.net/w5ze6/1/

Solution 2 - Jquery

Another approach, split by keyword and join with the updated html.

$("h2:contains('cow')").html(function(_, html) {
   return html.split('cow').join("<span class='smallcaps'>cow</span>");
});

Note: I haven't tested this, but I'm assuming this would perform worse than doing a replace, but figure I would include anyways for informative purposes

Solution 3 - Jquery

Here is a variation on @undefined's answer, which loops through an array of items:

var barnyardArray = [
    'cow',
    'horse',
    'chicken',
    'hog',
    'goat',
    'goose',
    'duck',
    'llama'
];

$.each(barnyardArray, function (index, value) {
    $("p:contains(" + value + ")").html(function (_, html) {
        var regex = new RegExp(value, 'g');
        return html.replace(regex, '<span class="smallcaps">' + value + '</span>');
    });
});

Solution 4 - Jquery

You usually want to match some arbitrary text in a case insensitive way. Sometimes, search queries contain characters that are special regex metacharacters and must be escaped before compiling the pattern.

Use a solution like

var words = ["cows", "c++", "$var$"];
$("h2").html(function(_, html) {
   return html.replace(new RegExp(words.map(function(x) { 
       return x.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
     }).join('|'), "gi"), '<span class="smallcaps">$&</span>')
});

span { color: red}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h2>We have cows on our farm</h2>
<h2>C++ Apps $var$</h2>

Note that here, a regex will look like /cows|c\+\+|\$var\$/gi, where + and $, special regex metacharacters, are escaped, and the alternatives are ORed with the | alternation operator.

Also, note that there is no need of any outer parentheses as the default group is Group 0 that holds the whole match, and the backreference to Group 0 in JavaScript regex is $&. Thus, the replacement is always done with the search word in the exact case as it was found in text.

Note that in case you need to match whole words only, you would need special boundaries, either \b (if the search words always consist of letters, digits or _) or (\W|^) / (?!\w) (if there can be special characters):

var words = ["cows", "c++", "$var$"];
$("h2").html(function(_, html) {
   return html.replace(new RegExp("(\\W|^)(" + words.map(function(x) { 
       return x.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
     }).join('|') + ")(?!\\w)", "gi"), '$1<span class="smallcaps">$2</span>')
});

span { color: red}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h2>We have cows in our farm cowshed</h2>
<h2>C++ Apps $var$ in $var$moretext</h2>

Solution 5 - Jquery

In my case i have some tag inside the target div and some text i need to wrap that text into a link.

This how i did following "What have you tried".

var oldText = $(this).text(),
newText = $(this).html().replace(
    oldText, 
    "<a class='k-link' href='#' class='smallcaps'>" + 
        oldText + 
    "<span class='k-icon k-i-arrow-n'></span></a>"
);
$(this).html(newText);

Solution 6 - Jquery

$("h2:contains('cow')").each(function() {
    var newText = $(this).html().replace("cow", "<span class='smallcaps'></span>");
    $(this).html(newText);
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSebView Question on Stackoverflow
Solution 1 - JqueryRamView Answer on Stackoverflow
Solution 2 - JqueryJustin BicknellView Answer on Stackoverflow
Solution 3 - JqueryJ7stinView Answer on Stackoverflow
Solution 4 - JqueryWiktor StribiżewView Answer on Stackoverflow
Solution 5 - JqueryShraftaliView Answer on Stackoverflow
Solution 6 - JqueryWhat have you triedView Answer on Stackoverflow