1

I want to replace all occurences of a pattern in a string by another string. For example, lets convert all "$" to "!":

"$$$" -> "!!!"

Plain string.replace replaces only the first match:

"$$$".replace("$", "!"); // gives "$!!"

and regexes force me to escape to special chars

"$$$".replace(/\$/g, "!"); // Pattern is now full of backslashes!

Is it possible to do the global replacement without having to manually escape the special characters? I have a bunch of patterns is a part of my code and I think readability would suffer if had to escape all of them by hand.

I'm expecting either a trick that directly does what I want or at least a way to convert a string to an excaped form useable by new RegExp

hugomg
  • 68,213
  • 24
  • 160
  • 246

4 Answers4

5

There is no standard regexp escape function in Javascript.

You can write your own (source) or get it from your library (dojo example)

function escape(s) {
    return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
};

This allows us to create the custom regex object at runtime

function replace_all(string, pattern, replacement){
    return string.replace( new RegExp(escape(pattern), "g"), replacement);
}
Community
  • 1
  • 1
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
1

try this:

function replaceAll(txt, replace, with_this) {
  return txt.replace(new RegExp(replace, 'g'),with_this);
}
Roman Goyenko
  • 6,965
  • 5
  • 48
  • 81
0

You can give the regest as a string and provide a third argument for the flags you want

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/replace

"$$$".replace("$", "!", "g");
Keith.Abramo
  • 6,952
  • 2
  • 32
  • 46
0

"Plain string.replace replaces only the first match"

In that case, depending on how efficient you need the replace operation to be, you could do:

String.prototype.my_replace_all_simple = function(f, r) {
    var newstr = "";
    for (var i = 0; i < this.length; ++i) {
        if (this[i] == f) {
            newstr += r;
        } else {
            newstr += this[i];
        }
    }
    return newstr;
};

or

String.prototype.my_replace_all = function (f, r) {
    if (this.length === 0 || f.length === 0) {
        return this;
    }
    var substart = 0;
    var end = this.length;
    var newstr = "";
    while (true) {
        var subend = this.indexOf(f, substart);
        if (subend === -1) subend = end;
        newstr += this.substring(substart, subend);
        if (subend === end) {
            break;
        }
        newstr += r;
        substart = subend + f.length;
    }
    return newstr;
};
// Adapted from C++ code that uses iterators.
// Might have converted it incorrectly though.

for example.

But, I'd just use Mark's suggested way.

Shadow2531
  • 11,980
  • 5
  • 35
  • 48
  • I don't want to have to re-implement naive string matching algorithms when I have a regex engine lying around... :) – hugomg Nov 10 '11 at 00:42