Is it possible to match "the dog is really really fat" in "The <strong>dog</strong> is really <em>really</em> fat!" and add "<span class="highlight">WHAT WAS MATCHED</span>" around it?

I don't mean this specifically, but generally be able to search text ignoring HTML, keeping it in the end result, and just add the span above around it all?

Considering the HTML tag overlapping problem, would it be possible to match a phrase and just add the span around each of the matched words? The problem here is that I don't want the word "dog" matched when it's not in the searched context, in this case, "the dog is really really fat."

  • 1
    Generally, no. Don't use RegEx for HTML. Use an HTML Parser. Also, please use the Code Highlighting functionality in StackOverflow. – g.d.d.c Sep 7 '11 at 19:05
  • 5
    He's not, he just want's to match specific text. – b01 Sep 7 '11 at 19:09
  • I don't have anything else I can touch except JavaScript. I thought I used backticks instead used quotes. – Francisc Sep 7 '11 at 19:09
  • It gets worse than this. What about <strong>I say the</strong> dog is <em>really really fat! What do</em> you say? Are you planning to make this look like: <strong>I say <span class="highlight">the</strong> dog is <em>really really fat!</span> What do</em> you say? – BishopRook Sep 7 '11 at 19:13
  • Good question, that's pretty crappy... – Francisc Sep 7 '11 at 19:16


Here is a working fiddle that does what you want. However, you will need to update the htmlTagRegEx to handle matching on any HTML tag, as this just performs a simple match and will not handle all the cases.


Also, below is the code. Basically, it takes out the html elements one by one, then does a replace in the text to add the highlight span around the matched selection, and then pushes back in the html elements one by one. It's ugly, but it's the easiest way I could think of to get it to work...

function highlightInElement(elementId, text){
    var elementHtml = document.getElementById(elementId).innerHTML;
    var tags = [];
    var tagLocations= [];
    var htmlTagRegEx = /<{1}\/{0,1}\w+>{1}/;

    //Strip the tags from the elementHtml and keep track of them
    var htmlTag;
    while(htmlTag = elementHtml.match(htmlTagRegEx)){
        tagLocations[tagLocations.length] = elementHtml.search(htmlTagRegEx);
        tags[tags.length] = htmlTag;
        elementHtml = elementHtml.replace(htmlTag, '');

    //Search for the text in the stripped html
    var textLocation = elementHtml.search(text);
        //Add the highlight
        var highlightHTMLStart = '<span class="highlight">';
        var highlightHTMLEnd = '</span>';
        elementHtml = elementHtml.replace(text, highlightHTMLStart + text + highlightHTMLEnd);

        //plug back in the HTML tags
        var textEndLocation = textLocation + text.length;
        for(i=tagLocations.length-1; i>=0; i--){
            var location = tagLocations[i];
            if(location > textEndLocation){
                location += highlightHTMLStart.length + highlightHTMLEnd.length;
            } else if(location > textLocation){
                location += highlightHTMLStart.length;
            elementHtml = elementHtml.substring(0,location) + tags[i] + elementHtml.substring(location);

    //Update the innerHTML of the element
    document.getElementById(elementId).innerHTML = elementHtml;
| improve this answer | |
  • Thanks, but I need to match text and still keep the tags. – Francisc Sep 7 '11 at 19:44
  • @Francisc: Do the text matching against the text. If it matches, then get the html with innerHTML. – Briguy37 Sep 7 '11 at 19:45
  • Yeah, but innerHTML of what? Text could be: <p>The dog is <i>really really</i> fat.</p>, I want to find dog is really and add <span> around that, but that would overlap the <i> element. – Francisc Sep 7 '11 at 20:16
  • @Francisc: Sorry about misunderstanding before. Please check my updated solution, as I think it now solves what you need to do. If you use it, I'd definitely advise looking into a more thorough regular expression. – Briguy37 Sep 7 '11 at 22:17
  • Wow, that must have taken a while to write. Thank you very much. – Francisc Sep 7 '11 at 23:12

Naah... just use the good old RegExp ;)

var htmlString = "The <strong>dog</strong> is really <em>really</em> fat!";
var regexp = /<\/?\w+((\s+\w+(\s*=\s*(?:\".*?"|'.*?'|[^'\">\s]+))?)+\s*|\s*)\/?>/gi;
var result = '<span class="highlight">' + htmlString.replace(regexp, '') + '</span>';
| improve this answer | |
  • 1
    That looks lovely... Is it Christmas yet? Anyway, I think that won't solve the overlapping HTML tags problem, will it? – Francisc Sep 7 '11 at 19:25
  • Where do you input the searched terms? :) – Francisc Sep 7 '11 at 19:31
  • sorry, I've missed the last one.. The regexp will match every html tag – Ivan Nikolchov Sep 7 '11 at 19:33
  • Oh, I think I understand, it strips out all HTML tags, right? – Francisc Sep 7 '11 at 19:34
  • Ah yes, what I needed was have it match some text as a human reads it and add the hightlight class. :) – Francisc Sep 7 '11 at 19:34

A simpler way with JQuery would be.

originalHtml = $("#div").html();

    newHtml = originalHtml.replace(new RegExp(keyword + "(?![^<>]*>)", "g"), function(e){
                      return "<span class='highlight'>" + e + "</span>";


This works just fine for me.

| improve this answer | |

Here is a working regex example to exclude matches inside html tags as well as javascripts:


Use this regex in a replace() script.

| improve this answer | |

You can use string replace with this expression </?\w*> and you'll get your string

| improve this answer | |

If you use jQuery, you can use the text property on the element containing the text you're searching for. Given this markup:

<p id="the-text">

This would yield "The dog is really really fat!":


You could do your regex search on that text instead of trying to do so in the markup.

Without jQuery, I'm unsure of an easy way to extract and concatenate the text nodes from all child elements.

| improve this answer | |
  • I don't think I can use jQuery. – Francisc Sep 7 '11 at 19:16
  • Oh, yeah I forgot about jQuery text. Why can't you use jQuery? – b01 Sep 7 '11 at 19:17

Your Answer

