DEV Community

Cover image for The JS string replace() method
ChooKing
ChooKing

Posted on

The JS string replace() method

Intro

The string replace() method is typically learned by Javascript students early in their studies, but only the basic form of usage is covered at that time, and the topic is usually not revisited later on. As a consequence, many Javascript developers only use it in its most basic form.

Basis Usage

The basic usage of replace() involves passing it two strings. The first is the string that is being replaced, and the second is the string that is used to replace it.

const strOriginal = "The quick brown fox jumps over the lazy dog.";
const strReplaced = strOriginal.replace("jumps", "flies");
console.log(strReplaced);
Enter fullscreen mode Exit fullscreen mode

That produces this output:

The quick brown fox flies over the lazy dog.
Enter fullscreen mode Exit fullscreen mode

Regular Expressions

Instead of providing a string as the first parameter to replace(), it is also possible to provide a regular expression.

const strOriginal = "The PIN is 1234."
const strReplaced = strOriginal.replace(/\b\d{4}\b/, "<redacted>");
console.log(strReplaced);//The PIN is <redacted>.
Enter fullscreen mode Exit fullscreen mode

The \d matches a digit, and the {4} matches exactly 4 of them. The \b at the beginning and end match boundaries. This prevents matching parts of numbers longer than 4 digits. In real world use, you might need extra code to distinguish the 4 digit sequence from part of a phone number or credit card number, but I left that out, because this is not intended to be a regex tutorial.

Replacer Function

The second parameter to the replace() method can be a function. Whatever this function returns is used to replace the matched text specified in the first parameter. This works both with strings and regular expressions provided as the first parameter.

When the first parameter of replace() is a string or a regex without capture groups, the replacer function is passed 3 parameters in the following order:

  1. matched text
  2. position of match
  3. original complete string

If the first parameter of replace() is a regex with capture groups, the second and all subsequent parameters, except the last two, will be the captures. The second to last will be the position of the first capture and the final parameter will be the original full string.

If a regular expression is used with the global flag, the function is called once for each match that is found.

The replacer function is less often accompanied by a string as the first parameter of the replace(), because a string is a constant value, so it's generally possible to pre-compute the substitute for it. However, it can be used with a string to do something like this:

const names = ["birds", "dogs", "cats", "pandas"];
const str = "We hold these truths to be self-evident, that all <ANIMALS> are created equal."
const strReplaced = str.replace("<ANIMALS>",
    ()=> names[Math.floor(Math.random() * names.length)]
);
console.log(strReplaced);

Enter fullscreen mode Exit fullscreen mode

This replaces "<ANIMALS>" with a randomly selected string from the names array to produce a random sentence like this:

We hold these truths to be self-evident, that all dogs are created equal.
Enter fullscreen mode Exit fullscreen mode

Combining RegEx with Replacer Function

The real power of the replacer function comes from combining it with a regular expression as the first parameter of the replace(). Because regex can match patterns, it can match strings that aren't known in advance, so a function might be needed to handle the matched text to produce its replacement.

Here is an example of converting snake case to camel case:

const snakeStr = "my_favorite_variable_name";
function snakeToCamelCase(str) {
    return str.replace(/_(\w)/g, function(_, letter) {
        return letter.toUpperCase();
    });
}
console.log(snakeToCamelCase(snakeStr)); //myFavoriteVariableName
Enter fullscreen mode Exit fullscreen mode

The \w matches a single character of text. It comes after an underscore in the regex, so it will match the first letter after an underscore. Parentheses are used to create a capture group which contains only this letter without the underscore as part of the string. (It would be simple to just take the second character of the match, but I wanted to illustrate capture groups.) This letter is received by the replacer function as its second parameter, and it is then capitalized and returned as a substitute for the whole substring that originally consisted of underscore and letter, so this erases the underscore and capitalizes the letter that comes after it.

Here is another example that converts hex color codes to rgb colors.

const css = `body{
    background-color: #88FF00;
    color: #0d2651;
}`;
const hex2RGB = str => str.replace(/#[0-9A-F]{6}/ig,(hex)=>{
    return "rgb(" +
        //skip first character which is #
        parseInt(hex.substring(1,3), 16) +
        ", " +
        parseInt(hex.substring(3,5), 16) +
        ", " +
        parseInt(hex.substring(5,7), 16) +
        ")";
});
console.log(hex2RGB(css));
Enter fullscreen mode Exit fullscreen mode

The resulting output is:

body{
    background-color: rgb(136, 255, 0);
    color: rgb(13, 38, 81);
}
Enter fullscreen mode Exit fullscreen mode

The regex matches the # followed immediately by exactly 6 hexadecimal digits, which are defined as character 0 through 9 and A through F. The i flag is used to ignore case, so it works both for upper and lower case. The replacer function takes substrings from the hex code and parses them to produce decimal numbers, and these numbers are placed in between "rgb(" and ")" to produce the rgb() colors.

Conclusion

There are many ways to modify an existing string, but using the replace() method is often a good choice when the goal is to substitute substrings based on content instead of position. Without it, the typical solution involves first searching the position of a substring, followed by splitting the string at that point and concatenating with a substitute, and that is not efficient.

Top comments (0)