22

Do any of the existing JavaScript frameworks have a non-regex replace() function, or has this already been posted on the web somewhere as a one-off function?

For example I want to replace "@!#$123=%" and I don't want to worry about which characters to escape. Most languages seem to have both methods of doing replacements. I would like to see this simple thing added.

5 Answers 5

33

i may be misunderstanding your question, but javascript does have a replace()

var string = '@!#$123=%';
var newstring = string.replace('@!#$123=%', 'hi');

edit: (see comments) the 5th edition does seem to have this info in it, although it doesn't show up when i link directly to it. here's the relevant part:

The replace( ) method performs a search-and-replace operation. It takes a regular expression as its first argument and a replacement string as its second argument. It searches the string on which it is called for matches with the specified pattern. If the regular expression has the g flag set, the replace( ) method replaces all matches in the string with the replacement string; otherwise, it replaces only the first match it finds. If the first argument to replace( ) is a string rather than a regular expression, the method searches for that string literally rather than converting it to a regular expression with the RegExp( ) constructor, as search( ) does.

Sign up to request clarification or add additional context in comments.

5 Comments

huh. maybe I was looking at an old version of "Javascript: The Definitive Guide" that only showed the regex example. so I never tried the above code. now I feel really dumb. -10 cool points for me.
Can someone check the most recent version of "Javascript: The Definitive Guide"? Is this kind of example now included?
Nick's answer below is more reliable for a "No-regex" option because the native replace method uses special characters in the replace string. So while replacing text with 'hi' is fine, replacing with anything containing '$' could cause unexpected results. Try "a".replace("a","$$b") as an example :)
The javascript function replaces only the first entry
This answer is answers the OP fine. The key is that replace() treats a string search value as a literal string. "$" is not treated specially, in that case. If, RegExp() is explicitly called, that has nothing to do with replace() since a RegExp object is being passed to replace(), not a string.
23

I had exactly the same problem searching for a non-regex javascript string replace() method. My solution was to use a combination of split() and join():

"some text containing regex interpreted characters: $1.00".split("$").join("£");

which gives:

"some text containing regex interpreted characters: £1.00"

compare with replace():

"some text containing regex interpreted characters: $1.00".replace(new RegExp("$"),"£")

which bizarrely gives:

"some text containing regex interpreted characters: $1.00£"

4 Comments

Not enough examples online would show you the simple replace method - "some text containing regex interpreted characters: $1.00".replace("$","£");
That's web programming: reinventing the wheel. JavaScript's replace() is a bad joke. Thanks for this hack. I think it's the best solution. +1
«$» means end of line in regular expression! So there's nothing strange with RegExp("$") which matches the end of your line as expected. You should have escaped your dollar before sending it to RegExp: RegExp("\$")
Note: this neatly replaces ALL occurrences. So s.split("$").join("£") is equivalent to s.replace(/\$/g, "£") or s.replace(RegExp("\\$", "g"), "£").
10

You'll still need to replace a few dollar sign combinations as specified on MDN.

This produces $bc not $$bc

'abc'.replace('a', '$$')

The best way to not worry about this is to use the function replace:

'abc'.replace('a', () => '$$')

1 Comment

This seems to be, by far, the best and simplest solution to this problem. It worked great for me. Thanks.
4

Try this:

function replaceAllTemp(str,find, replace) { 
var ignoreCase=true;
var _token;
var token=find;
var newToken=replace;
var i = -1;

if ( typeof token === "string" ) {

    if ( ignoreCase ) {

        _token = token.toLowerCase();

        while( (
            i = str.toLowerCase().indexOf(
                token, i >= 0 ? i + newToken.length : 0
            ) ) !== -1
        ) {
            str = str.substring( 0, i ) +
                newToken +
                str.substring( i + token.length );
        }

    } else {
        return this.split( token ).join( newToken );
    }

}
return str;
};

Comments

1

You can do it with or without ignoring case sensitivity.
Sadly, JavaScript's indexOf doesn't take locale vs. invariant as argument, so you'll have to replace toLowerCase with toLocaleLowerCase if you want to preserve culture-specifity.

function replaceAll(str, find, newToken, ignoreCase)
{
    var i = -1;

    if (!str)
    {
        // Instead of throwing, act as COALESCE if find == null/empty and str == null
        if ((str == null) && (find == null))
            return newToken;

        return str;
    }

    if (!find) // sanity check 
        return str;

    ignoreCase = ignoreCase || false;
    find = ignoreCase ? find.toLowerCase() : find;

    while ((
        i = (ignoreCase ? str.toLowerCase() : str).indexOf(
            find, i >= 0 ? i + newToken.length : 0
        )) !== -1
    )
    {
        str = str.substring(0, i) +
            newToken +
            str.substring(i + find.length);
    } // Whend 

    return str;
}

or as prototype:

if (!String.prototype.replaceAll ) {  
String.prototype.replaceAll = function (find, replace) {
    var str = this, i = -1;

    if (!str)
    {
        // Instead of throwing, act as COALESCE if find == null/empty and str == null
        if ((str == null) && (find == null))
            return newToken;

        return str;
    }

    if (!find) // sanity check 
        return str;

    ignoreCase = ignoreCase || false;
    find = ignoreCase ? find.toLowerCase() : find;

    while ((
        i = (ignoreCase ? str.toLowerCase() : str).indexOf(
            find, i >= 0 ? i + newToken.length : 0
        )) !== -1
    )
    {
        str = str.substring(0, i) +
            newToken +
            str.substring(i + find.length);
    } // Whend 

    return str;
};
}

2 Comments

Regex offers word boundary options with \b. Is there a way to modify this to not replace if the next character is alphanumeric?
or if you have any tips to add this ability

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.