63

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);
}
Inigo
  • 12,186
  • 5
  • 41
  • 70
James W Simms
  • 841
  • 1
  • 8
  • 9
  • 2
    Have you already checked this post ? http://stackoverflow.com/questions/1144783/replacing-all-occurrences-of-a-string-in-javascript – Patricia May 12 '16 at 21:11
  • Yes, among many others. However, after revisiting it, I have a better understanding on how the regular expression was being used. I modified the code above to reflect it. For me, it is a more concise answer. Perhaps it might help someone else. – James W Simms May 12 '16 at 22:54

3 Answers3

86

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');
basarat
  • 261,912
  • 58
  • 460
  • 511
  • Yes, the String.split().join() method is short and sweet. However, it is not possible to perform case insensitive search/replace. The first time I used the regex with the /g modifier, it generated an invalid pattern for regular expression during code execution. I needed to include the escape sequences to the pattern. `var pattern = oldValue.replace(/[-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");` That is why I like to include the entire function in my example. The procedure is simple and short enough to allow. – James W Simms May 16 '16 at 14:47
  • Love that split join stuff! – magnusarinell Feb 16 '17 at 11:27
  • 19
    Just as a reference, here the TypeScript replace call using regex: `myString.replace(/oldString/g, 'newString);` – Thomas Apr 22 '17 at 14:54
  • 1
    Regex fails when you have to replace special characters ( '[', ']' ) – Johan Aspeling Nov 20 '19 at 09:32
  • @JohanAspeling It need not fail. You can always escape speacial chars like `( '\[', '\]' )` – Sisir Jun 17 '21 at 08:10
11

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 How to replace all occurrences of a string in JavaScript?

Ziggler
  • 3,361
  • 3
  • 43
  • 61
4

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, '');