开发者

JavaScript RegExp match text ignoring HTML

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 specif开发者_高级运维ically, but generally be able to search text ignoring HTML, keeping it in the end result, and just add the span above around it all?

EDIT:

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."


Update:

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.

http://jsfiddle.net/briguy37/JyL4J/

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);
    if(textLocation){
        //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;
}


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>';


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

$("#div").html(newHtml);

This works just fine for me.


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

http://refiddle.com/lwy6

Use this regex in a replace() script.

    /(a)(?!([^<])*?>)(?!<script[^>]*?>)(?![^<]*?<\/script>|$)/gi


this.keywords.forEach(keyword => {
  el.innerHTML = el.innerHTML.replace(
    RegExp(keyword + '(?![^<>]*>)', 'ig'),
    matched => `<span class=highlight>${matched}</span>`
  )
})


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


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">
  The <strong>dog</strong> is really <em>really</em> fat!
</p>

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

$('#the-text').text();

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜