Skip to content Skip to sidebar Skip to footer

Wrap Character In String, Excluding A Link Tag With Javascript Regex

EDIT heres what i have to do... Imagine if i have a text with some html tags inside it (it is still a string): var string = '

Hello, my name is Mauricio

H

Solution 1:

I would recommend you to split the problem into 2 smaller problems:

  1. grab text content of all tags.
  2. wrap chars with <span class="ui-match"></span>

Using RegExp to parse HTML is a bad idea but in this case since you seem to control the input structure you might use it to simplify the logic.

Using a single RegExp for it will be really hard, so it's also better to do 2 String#replace instead of one. A generic implementation would be like:

functionreplaceHtmlContent(str, match, replaceFn) {
  // we use the "g" and "i" flags to make it replace all occurrences and ignore casevar re = newRegExp(match, 'gi');
  // this RegExp will match any char sequence that doesn't contain "<" or ">"// and that is followed by a tagreturn str.replace(/([^<>]+)(?=<[^>]+>)/g, function(s, content){
    return content.replace(re, replaceFn);
  });
}

which could be abstracted as:

functionwrapMatch(src, match) {
  return replaceHtmlContent(src, match, function(str){
    return'<span class="ui-match">'+ str +'</span>';
  });
}

and used later like:

var output = wrapMatch(input, 'a');

which would give the expected result for the example input.

DEMO:http://jsbin.com/ovUFEsas/4/edit

Solution 2:

For not using regex, it will be faster to work with DOM nodes:

var div = document.createElement('div'),
    children;

div.innerHTML = 'Hello, my name is mauricio, and i like <a href="#">Star Wars</a>';
children = div.childNodes;

for (var i = 0, len = children.length; i < len; i++) {
    console.log(children[i]);
    if (children[i].nodeType === 3) {
        children[i].nodeValue = children[i].nodeValue.replace(/a/g, 'R');
    }
}

console.log(div.innerHTML);

N.B.: I used innerHTML property as an example way here, however it is not recommended to exploit it because of a rather low performance.

DEMO:http://jsfiddle.net/N7rdW/


UPDATE:

As per your update, you should better use the approach from my answer for another question from HERE. The code is a bit more complicated but is rather fast (not keeping in mind innerHTML usage):

var div = document.createElement('div');
div.innerHTML = 'Hello, my name is mauricio, and i like <a href="#">Star Wars</a>';

for (var i = 0, children = div.childNodes, len = children.length; i < len; i++) {
    var child = children[i];
    if (child.nodeType === 3 && child.nodeValue.indexOf('a') > -1) {
        var segments = child.nodeValue.split('a');
        for (var k = 0, lk = segments.length; k < lk; k++) {
            div.insertBefore(document.createTextNode(segments[k]), child);
            if (k < lk - 1) {
                var span = document.createElement('span');
                span.className = 'ui-match';
                span.appendChild(document.createTextNode('R'));
                div.insertBefore(span, child);
            }
        }
        div.removeChild(child);
    }
}

console.log(div.innerHTML);

DEMO:http://jsfiddle.net/T4ZXA/6/

Post a Comment for "Wrap Character In String, Excluding A Link Tag With Javascript Regex"