String.Replace only replaces first occurrence of matched string. How to replace *all* occurrences?

JavascriptRegexTypescript

Javascript Problem Overview


Coming from other programming languages, String.replace() typically replaces all occurrences of matching strings. However, that is not the case with javascript/typescript. I found a number of solutions on the web with javascript utilizing regex. I immediately had issues with this solution because of special characters. I suspect there is a way to correct this with regex, but I am not a regex expert. As many have done before me, I created my own method.

Perhaps there are ways to improve performance by making use of a custom StringBuilder() class. I welcome any thoughts.

public static Replace = function (originalString: string, oldValue: string, newValue: string, ignoreCase: boolean = false) {
    //
    // if invalid data, return the original string
    //
    if ((originalString == null) || (oldValue == null) || (newValue == null) || (oldValue.length == 0) )
        return (originalString);
    //
    // do text replacement
    //
    var dest = "";        
    var source: string = originalString;
    if (ignoreCase) 
    {
        source = source.toLocaleLowerCase();
        oldValue = oldValue.toLowerCase();
    }
    //
    // find first match
    //
    var StartPos = 0;
    var EndPos = source.indexOf(oldValue, StartPos);
    var Skip = (EndPos >= 0) ? EndPos - StartPos : source.length-StartPos;   
    //
    // while we found a matched string
    //     
    while (EndPos > -1) {
        //
        // copy original string skipped segment
        //
        if (Skip > 0) dest += originalString.substr(StartPos, Skip);            
        //
        // copy new value
        //
        dest += newValue;
        //
        // skip over old value
        //
        StartPos = EndPos + oldValue.length;
        //
        // find next match
        //
        EndPos = source.indexOf(oldValue, StartPos);
        Skip = (EndPos >= 0) ? EndPos - StartPos : source.length - StartPos;    
    }
    //
    // append the last skipped string segment from original string
    //
    if (Skip > 0) dest += originalString.substr(StartPos, Skip);   
    
    return dest;
}

In order to add support to this method to the string class I added the following code:

interface String { EZReplace(oldValue: string, newValue: string, ignorCase?: boolean): string; }

String.prototype.EZReplace = function (oldValue: string, newValue: string, ignorCase: boolean = false) {
return EZUtil.Replace(this, oldValue, newValue, ignorCase);}

....After re-viewing other posts, I modified the code to use regular expressions. It would be interesting to execute performance tests.

 public static Replace = function (originalString: string, oldValue: string, newValue: string, ignoreCase: boolean = false) {
    //
    // if invalid data, return the original string
    //
    if ((originalString == null) || (oldValue == null) || (newValue == null) || (oldValue.length == 0))
        return (originalString);
    //
    // set search/replace flags
    //
    var Flags: string = (ignoreCase) ? "gi" : "g";
    //
    // apply regex escape sequence on pattern (oldValue)
    //
    var pattern = oldValue.replace(/[-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
    //
    // replace oldValue with newValue
    //
    var str = originalString.replace(new RegExp(pattern, Flags), newValue);
    return (str);
}

Javascript Solutions


Solution 1 - Javascript

> In typescript, String.Replace only replaces first occurrence of matched string. Need String.replaceAll() method

There is nothing special to TypeScript here (after all TypeScript is just JavaScript with type annotations). JavaScript string.replace only replaces the first instance if given a string. Only way to get replace all is to use a regex with /g modifier.

Alternatively I just do:

somestring.split('oldString').join('newString');

Solution 2 - Javascript

In my case I did like this in TypeScript.

this.mystr= this.mystr.replace(new RegExp('class="dec-table"', 'g'), 'class="copydec-table"');

Credits to https://stackoverflow.com/questions/1144783/how-to-replace-all-occurrences-of-a-string-in-javascript

Solution 3 - Javascript

In my case, I'm using Node 12+. And there is no .replaceAll() for Node (Check the Browser Compatibility on MDN).

But my solution is using Regex(/g) with .replace(). The key is using /g.

const s = `[People,Contracts,Facilities]`;
// My case was to remove the `[` and `]`
// So the key is using `/g`
const res = s.replace(/\[/g, '').replace(/\]/g, '');

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJames W SimmsView Question on Stackoverflow
Solution 1 - JavascriptbasaratView Answer on Stackoverflow
Solution 2 - JavascriptZigglerView Answer on Stackoverflow
Solution 3 - JavascriptCharlieIsAwesomeView Answer on Stackoverflow