1

I am replacing words in a string and I'm trying to match based on '\b' + myword + '\b' However this does not work when myword has a non word character on either end.

var myword1 = "testword,";
var myword2 = "(testword";
var testString = "<tag>asdftestword, is a (testwordasdf also (testword </tag> (testword, should be replaced everywhere there is a testword,)";

var rx1 = new RegExp(???(myword1) ,'g');
var rx2 = new RegExp(???(myword2) ,'g');
var result1 = testString.replace(rx1, "replacement");
var result2 = testString.replace(rx2, "replacement");

I would like the results to be

result1 == "<tag>asdftestword, is a (testwordasdf also (testword </tag> (replacement should be replaced everywhere there is a replacement)"
result2 == "<tag>asdftestword, is a (testwordasdf also replacement </tag> replacement, should be replaced everywhere there is a testword,)"
Biff MaGriff
  • 8,102
  • 9
  • 61
  • 98
  • 4
    You cannot create a regular expressions this way, not matter which characters `myword` contains. Have a look at [how to pass a variable into an regular expression in javascript](http://stackoverflow.com/questions/8574498/how-to-pass-a-variable-into-an-regular-expression-in-javascript). – Felix Kling Feb 28 '12 at 22:33
  • 1
    That applies to all punctuation marks, that they're characters other than \b (beginning/end of word). That's normal. – inhan Feb 28 '12 at 22:34

4 Answers4

1
testString.replace( new RegExp('\\b'+myword+'\\b','g'), "replacement");

However, if myword may contain characters that are special in a regex (e.g. parens, periods, brackets, etc.) then you'll need to escape them first:

RegExp.escape = function(text) {
  if (!RegExp.sRE) {
    var chars = '/.*+?|()[]{}\\'.split('');
    RegExp.sRE = new RegExp('\\'+chars.join('|\\'), 'g');
  }
  return text.replace(RegExp.sRE, '\\$&');
}

var re = new RegExp('\\b'+RegExp.escape(myword)+'\\b','g');
Phrogz
  • 296,393
  • 112
  • 651
  • 745
0

Ok, I've finally figured this out. It looks like it is too complex to do with just a single RegExp I need multiple!

See it in action Here

function EscapeRegex(text) {
    if (!RegExp.sRE) {
    var chars = '/.*+?|()[]{}\\'.split('');
    RegExp.sRE = new RegExp('\\'+chars.join('|\\'), 'g');
    }
    return text.replace(RegExp.sRE, '\\$&');
}

function ReplaceWholeWord(subjectString, wordtofind, replacement){
    var escapedWord = EscapeRegex(wordtofind);
    //simplest scenaro, word to find has non-word characters at begining and end - do basic replace
    if(regexIndexOf(escapedWord, '[^\\w]', 0) == 0 && regexLastIndexOf(escapedWord, '[^\\w]', 0) == wordtofind.length - 1){
        subjectString = subjectString.replace(new RegExp(escapedWord, 'g'), replacement);
    }
    //word to find begins with non-wordcharacter
    else if(regexIndexOf(escapedWord, '[^\\w]', 0) == 0){
        var index = regexIndexOf(subjectString, escapedWord+'[^\\w]', index);
        while(index > 0){
            subjectString = subjectString.substring(0, index) + replacement + subjectString.substring(index + wordtofind.length);
            index = regexIndexOf(subjectString, escapedWord+'[^\\w]', index);
        }
    }
    //word to find ends with non-wordcharacter
    else if(regexLastIndexOf(escapedWord, '[^\\w]', 0) == wordtofind.length - 1){
        var index = regexIndexOf(subjectString, '[^\\w]'+escapedWord, index);
        while(index > 0){
            subjectString = subjectString.substring(0, index) + replacement + subjectString.substring(index + myword.length + 1);
            index = regexIndexOf(subjectString, escapedWord+'[^\\w]', index);
        }
    }
    //word is normal
    else{
        var index = regexIndexOf(subjectString,'[^\\w]'+escapedWord+'[^\\w]', index);
        while(index >= 0){
            subjectString = subjectString.substring(0, index + 1) + replacement + subjectString.substring(index + wordtofind.length + 1);
            index = regexIndexOf(subjectString,'[^\\w]'+escapedWord+'[^\\w]', index);
        }
    }
    return subjectString;
}
Biff MaGriff
  • 8,102
  • 9
  • 61
  • 98
0

You don't need regex for this. Just use normal string replace:

var myword = "testword,";
var testString = "<tag>asdftestword, is a testword</tag> (testword, should be replaced everywhere there is a testword,)";

var result = testString.replace( myword , "replacement");
Johnny Sparks
  • 360
  • 2
  • 7
  • I need it to ignore `asdftestword,` http://jsfiddle.net/g4f8s/ yeilds `asdfreplacement is a testword (testword, should be replaced everywhere there is a testword,)` – Biff MaGriff Feb 28 '12 at 22:39
  • JavaScript's `String.prototype.replace` only replaces the first occurrence; you must use a regex with the `/g` flag to replace all occurrences. (Or use other silly looping constructs.) – Phrogz Feb 28 '12 at 22:40
  • fixed with a regex global flag `var result = testString.replace( /testword,/g , "replacement");` – deltree Feb 28 '12 at 22:44
0
var rx = new RegExp('\\b' + myword ,'g');
var result = testString.replace(rx, 'replacement');
inhan
  • 7,394
  • 2
  • 24
  • 35