DevToolBoxGRATIS
Blog

JavaScript String Replace met Regex: replaceAll, Capture Groups & Voorbeelden

7 min lezenby DevToolBox

JavaScript String.prototype.replace() and replaceAll() are two of the most frequently used methods for text manipulation. Combined with regular expressions, they unlock powerful pattern-based transformations: capture groups, named groups, callback functions, and more. This guide covers everything from basics to 15 production-ready examples you can copy-paste today.

Test your regex patterns live in our Regex Tester β†’

1. replace() vs replaceAll() β€” Key Difference

The fundamental difference: replace() only replaces the first match when given a string argument, while replaceAll() replaces every occurrence. When using a regex with the /g flag, both behave identically.

// replace() β€” only replaces the FIRST match with a string argument
const str = 'foo bar foo baz foo';

console.log(str.replace('foo', 'qux'));
// Output: "qux bar foo baz foo"

// replaceAll() β€” replaces EVERY match (ES2021)
console.log(str.replaceAll('foo', 'qux'));
// Output: "qux bar qux baz qux"

// replace() with regex /g β€” also replaces every match
console.log(str.replace(/foo/g, 'qux'));
// Output: "qux bar qux baz qux"
// Quick comparison table:
// β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
// β”‚ Method                       β”‚ String arg         β”‚ Regex /g arg     β”‚
// β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
// β”‚ str.replace(search, rep)     β”‚ First match only   β”‚ All matches      β”‚
// β”‚ str.replaceAll(search, rep)  β”‚ All matches        β”‚ All matches      β”‚
// β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

2. Basic Regex Replace: The /g Flag

To replace all occurrences with replace(), pass a regex with the global (g) flag. This has been the standard approach since ES3 and works in every JavaScript environment.

// Replace all digits with '#'
const masked = 'Order 12345, ID 67890'.replace(/\d/g, '#');
console.log(masked);
// Output: "Order #####, ID #####"

// Replace all vowels (case-insensitive with 'i' flag)
const noVowels = 'Hello World'.replace(/[aeiou]/gi, '_');
console.log(noVowels);
// Output: "H_ll_ W_rld"

// Replace all whitespace sequences with a single space
const cleaned = 'too   many    spaces   here'.replace(/\s+/g, ' ');
console.log(cleaned);
// Output: "too many spaces here"

// Remove all non-alphanumeric characters
const alphaOnly = 'Hello, World! @2024'.replace(/[^a-zA-Z0-9]/g, '');
console.log(alphaOnly);
// Output: "HelloWorld2024"

// Case-insensitive replacement
const result = 'Hello HELLO hello'.replace(/hello/gi, 'hi');
console.log(result);
// Output: "hi hi hi"

3. Capture Groups: $1, $2 in Replacement String

Capture groups (...) let you reference matched sub-expressions in the replacement string using $1, $2, etc. The entire match is available as $&.

// Swap first and last name using $1 and $2
const name = 'John Smith';
const swapped = name.replace(/(\w+) (\w+)/, '$2, $1');
console.log(swapped);
// Output: "Smith, John"

// Reformat a date: MM/DD/YYYY β†’ YYYY-MM-DD
const date = '12/25/2024';
const isoDate = date.replace(/(\d{2})\/(\d{2})\/(\d{4})/, '$3-$1-$2');
console.log(isoDate);
// Output: "2024-12-25"

// Wrap each word in <strong> tags using $&
const bold = 'hello world'.replace(/\w+/g, '<strong>$&</strong>');
console.log(bold);
// Output: "<strong>hello</strong> <strong>world</strong>"

// Use $` (before match) and $' (after match)
const demo = 'abc-def-ghi'.replace(/-def-/, '[$`|$&|$\']');
console.log(demo);
// Output: "abc[abc|-def-|ghi]ghi"

// Multiple capture groups: restructure a log entry
const log = '[ERROR] 2024-01-15 Connection timeout';
const parsed = log.replace(
  /\[(\w+)\] (\d{4}-\d{2}-\d{2}) (.+)/,
  'Date: $2 | Level: $1 | Message: $3'
);
console.log(parsed);
// Output: "Date: 2024-01-15 | Level: ERROR | Message: Connection timeout"

4. Named Capture Groups: (?<name>...)

Named capture groups (ES2018) improve readability by assigning a name to each group. Reference them in the replacement string with $<name>.

// Named capture groups with $<name> syntax (ES2018+)
const dateStr = '2024-12-25';
const formatted = dateStr.replace(
  /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/,
  '$<month>/$<day>/$<year>'
);
console.log(formatted);
// Output: "12/25/2024"

// Named groups in a callback function
const url = 'https://example.com:8080/path';
const parts = url.replace(
  /(?<protocol>https?):\/\/(?<host>[^:]+):(?<port>\d+)/,
  (match, _p1, _p2, _p3, _offset, _str, groups) => {
    return `Protocol=${groups.protocol} Host=${groups.host} Port=${groups.port}`;
  }
);
console.log(parts);
// Output: "Protocol=https Host=example.com Port=8080/path"

// Combining named and numbered groups
const input = 'John Doe, age 30';
const output = input.replace(
  /(?<first>\w+) (?<last>\w+), age (?<age>\d+)/,
  '$<last>, $<first> (age: $<age>)'
);
console.log(output);
// Output: "Doe, John (age: 30)"

5. Callback Function: replace(regex, fn)

For dynamic replacements, pass a function as the second argument. The callback receives the full match, each capture group, the offset, and the original string.

// Callback signature:
// replace(regex, (match, p1, p2, ..., offset, string, groups) => newString)

// Uppercase every word
const title = 'the quick brown fox'.replace(
  /\b\w/g,
  (char) => char.toUpperCase()
);
console.log(title);
// Output: "The Quick Brown Fox"

// Double every number found in a string
const doubled = 'I have 3 cats and 12 fish'.replace(
  /\d+/g,
  (match) => String(Number(match) * 2)
);
console.log(doubled);
// Output: "I have 6 cats and 24 fish"

// Convert hex color to rgb
const hexToRgb = '#ff8800'.replace(
  /#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})/i,
  (_match, r, g, b) => {
    return `rgb(${parseInt(r, 16)}, ${parseInt(g, 16)}, ${parseInt(b, 16)})`;
  }
);
console.log(hexToRgb);
// Output: "rgb(255, 136, 0)"

// Use offset parameter: show match positions
const positions: string[] = [];
'abcabc'.replace(/b/g, (match, offset) => {
  positions.push(`"${match}" at index ${offset}`);
  return match;
});
console.log(positions);
// Output: ['"b" at index 1', '"b" at index 4']

// Conditional replacement based on capture groups
const env = 'DB_HOST=localhost DB_PORT=5432 DB_PASS=secret123';
const redacted = env.replace(
  /(\w+)=(\S+)/g,
  (_match, key, value) => {
    return key.includes('PASS') ? `${key}=****` : `${key}=${value}`;
  }
);
console.log(redacted);
// Output: "DB_HOST=localhost DB_PORT=5432 DB_PASS=****"

6. 15 Practical Examples

Each example below is a self-contained, runnable snippet. Copy-paste into your browser console or Node.js REPL to test immediately.

Example 1: camelCase to kebab-case

function camelToKebab(str) {
  return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
}

console.log(camelToKebab('backgroundColor'));  // "background-color"
console.log(camelToKebab('fontSize'));          // "font-size"
console.log(camelToKebab('borderTopWidth'));    // "border-top-width"
console.log(camelToKebab('XMLHttpRequest'));    // "xmlhttp-request"

Example 2: Remove HTML Tags

function stripHtml(html) {
  return html.replace(/<[^>]*>/g, '');
}

console.log(stripHtml('<p>Hello <b>world</b></p>'));
// Output: "Hello world"

console.log(stripHtml('<div class="test">Content <br/> here</div>'));
// Output: "Content  here"

// Also remove &entities;
function stripHtmlFull(html) {
  return html
    .replace(/<[^>]*>/g, '')
    .replace(/&[a-zA-Z]+;/g, ' ')
    .replace(/\s+/g, ' ')
    .trim();
}

console.log(stripHtmlFull('<p>Price:&nbsp;$100&amp;up</p>'));
// Output: "Price: $100 up"

Example 3: Mask Email Address

function maskEmail(email) {
  return email.replace(
    /^(.)(.*)(@.+)$/,
    (_match, first, middle, domain) => {
      return first + '*'.repeat(middle.length) + domain;
    }
  );
}

console.log(maskEmail('alice@example.com'));   // "a****@example.com"
console.log(maskEmail('bob@gmail.com'));       // "b**@gmail.com"
console.log(maskEmail('charlie@company.io')); // "c******@company.io"

Example 4: Format Phone Number

function formatPhone(phone) {
  // Strip all non-digits first
  const digits = phone.replace(/\D/g, '');
  // Format as (xxx) xxx-xxxx
  return digits.replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');
}

console.log(formatPhone('1234567890'));     // "(123) 456-7890"
console.log(formatPhone('123-456-7890'));   // "(123) 456-7890"
console.log(formatPhone('(123) 456 7890')); // "(123) 456-7890"
console.log(formatPhone('+1-234-567-8901')); // "(123) 456-7890" (first digit stripped)

// International format variant
function formatPhoneIntl(phone) {
  const digits = phone.replace(/\D/g, '');
  return digits.replace(/(\d{1})(\d{3})(\d{3})(\d{4})/, '+$1 ($2) $3-$4');
}

console.log(formatPhoneIntl('12345678901')); // "+1 (234) 567-8901"

Example 5: Trim Extra Whitespace

function trimWhitespace(str) {
  return str
    .replace(/^\s+|\s+$/g, '')   // trim leading & trailing
    .replace(/\s+/g, ' ');         // collapse internal spaces
}

console.log(trimWhitespace('  hello   world  '));
// Output: "hello world"

console.log(trimWhitespace('\t  line1  \n  line2  \t'));
// Output: "line1 line2"

// Remove blank lines from multiline text
function removeBlankLines(text) {
  return text.replace(/^\s*\n/gm, '');
}

console.log(removeBlankLines('line1\n\n\nline2\n\nline3'));
// Output: "line1\nline2\nline3"

Example 6: Slugify a Title

function slugify(title) {
  return title
    .toLowerCase()
    .replace(/[^a-z0-9\s-]/g, '')   // remove special chars
    .replace(/\s+/g, '-')            // spaces to hyphens
    .replace(/-+/g, '-')             // collapse multiple hyphens
    .replace(/^-|-$/g, '');          // trim leading/trailing hyphens
}

console.log(slugify('Hello World!'));
// Output: "hello-world"

console.log(slugify('  JavaScript String Replace --- with Regex!  '));
// Output: "javascript-string-replace-with-regex"

console.log(slugify('10 Tips & Tricks for React.js'));
// Output: "10-tips--tricks-for-reactjs"

Example 7: Capitalize Each Word (Title Case)

function titleCase(str) {
  return str
    .toLowerCase()
    .replace(/\b\w/g, (char) => char.toUpperCase());
}

console.log(titleCase('hello world'));           // "Hello World"
console.log(titleCase('JAVASCRIPT IS FUN'));     // "Javascript Is Fun"
console.log(titleCase('the quick brown fox'));   // "The Quick Brown Fox"

// Smarter version: skip small words (a, an, the, in, on, etc.)
function smartTitleCase(str) {
  const small = new Set(['a', 'an', 'the', 'in', 'on', 'at', 'to', 'for', 'of', 'and', 'but', 'or']);
  return str
    .toLowerCase()
    .replace(/\b\w+/g, (word, index) => {
      if (index > 0 && small.has(word)) return word;
      return word.charAt(0).toUpperCase() + word.slice(1);
    });
}

console.log(smartTitleCase('the lord of the rings'));
// Output: "The Lord of the Rings"

Example 8: Swap Two Words

function swapWords(str, word1, word2) {
  const regex = new RegExp(`\\b(${word1}|${word2})\\b`, 'gi');
  return str.replace(regex, (match) => {
    return match.toLowerCase() === word1.toLowerCase() ? word2 : word1;
  });
}

console.log(swapWords('Hello World', 'Hello', 'World'));
// Output: "World Hello"

console.log(swapWords('left is right and right is left', 'left', 'right'));
// Output: "right is left and left is right"

// Swap using capture groups only (no function needed)
const swapped = 'foo bar'.replace(/(\w+) (\w+)/, '$2 $1');
console.log(swapped);
// Output: "bar foo"

Example 9: Remove Consecutive Duplicate Words

function removeDuplicateWords(str) {
  return str.replace(/\b(\w+)\s+\1\b/gi, '$1');
}

console.log(removeDuplicateWords('the the quick brown fox'));
// Output: "the quick brown fox"

console.log(removeDuplicateWords('hello hello world world'));
// Output: "hello world"

console.log(removeDuplicateWords('I I am am very very happy'));
// Output: "I am very happy"

// Remove all consecutive duplicates (even more than 2)
function removeAllDuplicateWords(str) {
  return str.replace(/\b(\w+)(?:\s+\1)+\b/gi, '$1');
}

console.log(removeAllDuplicateWords('no no no no duplicates'));
// Output: "no duplicates"

Example 10: Add Commas to Numbers

function addCommas(num) {
  return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

console.log(addCommas(1234567));       // "1,234,567"
console.log(addCommas(1000));          // "1,000"
console.log(addCommas(100));           // "100"
console.log(addCommas(1234567890));    // "1,234,567,890"

// Handle decimals too
function addCommasDecimal(numStr) {
  const [integer, decimal] = numStr.split('.');
  const formatted = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
  return decimal ? `${formatted}.${decimal}` : formatted;
}

console.log(addCommasDecimal('1234567.89'));  // "1,234,567.89"
console.log(addCommasDecimal('1000000.5'));   // "1,000,000.5"

Example 11: Extract Domain from URL

function extractDomain(url) {
  return url.replace(/^(?:https?:\/\/)?(?:www\.)?([^\/:]+).*$/, '$1');
}

console.log(extractDomain('https://www.example.com/path'));
// Output: "example.com"

console.log(extractDomain('http://blog.example.com:8080/post'));
// Output: "blog.example.com"

console.log(extractDomain('https://sub.domain.co.uk/page?q=1'));
// Output: "sub.domain.co.uk"

// Extract just the root domain (without subdomains)
function extractRootDomain(url) {
  const domain = url.replace(/^(?:https?:\/\/)?(?:www\.)?([^\/:]+).*$/, '$1');
  const parts = domain.split('.');
  return parts.slice(-2).join('.');
}

console.log(extractRootDomain('https://blog.shop.example.com'));
// Output: "example.com"

Example 12: Replace Only the Nth Occurrence

function replaceNth(str, pattern, replacement, n) {
  let count = 0;
  return str.replace(new RegExp(pattern, 'g'), (match) => {
    count++;
    return count === n ? replacement : match;
  });
}

console.log(replaceNth('a-b-c-d-e', '-', ' | ', 3));
// Output: "a-b-c | d-e"

console.log(replaceNth('foo bar foo baz foo', 'foo', 'QUX', 2));
// Output: "foo bar QUX baz foo"

// Replace every Nth occurrence
function replaceEveryNth(str, pattern, replacement, n) {
  let count = 0;
  return str.replace(new RegExp(pattern, 'g'), (match) => {
    count++;
    return count % n === 0 ? replacement : match;
  });
}

console.log(replaceEveryNth('a,b,c,d,e,f', ',', ' | ', 2));
// Output: "a,b | c,d | e,f"

Example 13: Convert Template Variables

function interpolate(template, data) {
  return template.replace(
    /\{\{\s*(\w+)\s*\}\}/g,
    (_match, key) => data[key] ?? `{{${key}}}`
  );
}

const tpl = 'Hello {{ name }}, welcome to {{ city }}!';
const data = { name: 'Alice', city: 'Tokyo' };

console.log(interpolate(tpl, data));
// Output: "Hello Alice, welcome to Tokyo!"

// With missing key fallback
console.log(interpolate('Hi {{name}}, your role is {{role}}', { name: 'Bob' }));
// Output: "Hi Bob, your role is {{role}}"

// Dollar-sign template syntax
function interpolateDollar(template, data) {
  return template.replace(
    /\$\{(\w+)\}/g,
    (_match, key) => data[key] ?? ''
  );
}

console.log(interpolateDollar('User: ${user}, ID: ${id}', { user: 'admin', id: '42' }));
// Output: "User: admin, ID: 42"

Example 14: Escape HTML Entities

function escapeHtml(str) {
  const map = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#039;',
  };
  return str.replace(/[&<>"']/g, (char) => map[char]);
}

console.log(escapeHtml('<script>alert("XSS")</script>'));
// Output: "&lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;"

console.log(escapeHtml('Price: $5 < $10 & "free" > 'nothing''));
// Output: "Price: $5 &lt; $10 &amp; &quot;free&quot; &gt; &#039;nothing&#039;"

// Reverse: unescape HTML entities
function unescapeHtml(str) {
  const map = {
    '&amp;': '&',
    '&lt;': '<',
    '&gt;': '>',
    '&quot;': '"',
    '&#039;': "'",
  };
  return str.replace(/&(?:amp|lt|gt|quot|#039);/g, (entity) => map[entity]);
}

console.log(unescapeHtml('&lt;p&gt;Hello&lt;/p&gt;'));
// Output: "<p>Hello</p>"

Example 15: Censor Profanity with Asterisks

function censorWords(text, wordList) {
  const pattern = new RegExp(
    '\\b(' + wordList.join('|') + ')\\b',
    'gi'
  );
  return text.replace(pattern, (match) => '*'.repeat(match.length));
}

console.log(censorWords('This is a damn bad example', ['damn', 'bad']));
// Output: "This is a **** *** example"

console.log(censorWords('Foo and Bar walked into a baz', ['foo', 'bar', 'baz']));
// Output: "*** and *** walked into a ***"

// Partial censoring: keep first and last letter
function partialCensor(text, wordList) {
  const pattern = new RegExp('\\b(' + wordList.join('|') + ')\\b', 'gi');
  return text.replace(pattern, (match) => {
    if (match.length <= 2) return '*'.repeat(match.length);
    return match[0] + '*'.repeat(match.length - 2) + match[match.length - 1];
  });
}

console.log(partialCensor('That was a damn bad move', ['damn', 'bad']));
// Output: "That was a d**n b*d move"

7. replaceAll with String vs Regex

replaceAll() accepts both a string and a regex. When using a regex, the g flag is required, otherwise a TypeError is thrown. With a plain string, no special syntax is needed.

// βœ… replaceAll with a string β€” simple and effective
const str1 = 'foo.bar.baz';
console.log(str1.replaceAll('.', '/'));
// Output: "foo/bar/baz"

// βœ… replaceAll with regex + /g flag β€” works fine
const str2 = 'foo123bar456baz';
console.log(str2.replaceAll(/\d+/g, '#'));
// Output: "foo#bar#baz"

// ❌ replaceAll with regex WITHOUT /g β€” throws TypeError!
try {
  'hello'.replaceAll(/hello/, 'world');
} catch (e) {
  console.log(e.message);
  // "String.prototype.replaceAll called with a non-global RegExp argument"
}

// String replaceAll does NOT interpret regex special chars
const str3 = 'price is $100.00 (USD)';
console.log(str3.replaceAll('$100.00', '€85.50'));
// Output: "price is €85.50 (USD)"
// No need to escape $ or . β€” they are treated as literal characters

// But replace() with string also only matches literally
const str4 = 'a.b.c';
console.log(str4.replace('.', '-'));  // "a-b.c" (first only)
console.log(str4.replaceAll('.', '-')); // "a-b-c" (all)

8. Performance Tips

String replacement with regex is fast for most use cases, but there are pitfalls to avoid in performance-critical code.

  • Pre-compile regex outside loops: Creating a new RegExp() inside a loop is wasteful. Declare it once and reuse it.
  • Avoid catastrophic backtracking: Patterns like (a+)+b can cause exponential execution time on non-matching input. Use atomic-style patterns or be specific with character classes.
  • Use string methods when possible: If you are replacing a literal string (no pattern), replaceAll(string, string) is faster than a regex.
  • Prefer non-capturing groups: Use (?:...) instead of (...) when you do not need backreferences. This reduces memory overhead.
  • Benchmark with realistic data: Use performance.now() to measure replacement time on actual input sizes.
// ❌ Bad: regex created inside loop
function processItemsBad(items) {
  return items.map(item => item.replace(new RegExp('\\s+', 'g'), '-'));
}

// βœ… Good: regex pre-compiled outside loop
const WHITESPACE_RE = /\s+/g;
function processItemsGood(items) {
  return items.map(item => item.replace(WHITESPACE_RE, '-'));
}

// ⚠️ Catastrophic backtracking example
// This pattern can hang the browser on non-matching input:
// const badRegex = /^(a+)+b$/;
// badRegex.test('aaaaaaaaaaaaaaaaaaaaaaaaaac'); // extremely slow!

// βœ… Safe equivalent:
const goodRegex = /^a+b$/;

// Benchmark template
function benchmark(fn, iterations = 100000) {
  const start = performance.now();
  for (let i = 0; i < iterations; i++) fn();
  const end = performance.now();
  console.log(`${iterations} iterations: ${(end - start).toFixed(2)}ms`);
}

// Compare string vs regex performance
const testStr = 'hello world hello world hello world';
benchmark(() => testStr.replaceAll('hello', 'hi'));      // string method
benchmark(() => testStr.replace(/hello/g, 'hi'));         // regex method

9. TypeScript Types for replace

TypeScript fully supports replace() and replaceAll() with proper type inference. Here are the key type signatures and patterns for type-safe replacements.

// TypeScript signatures for replace and replaceAll:
//
// interface String {
//   replace(searchValue: string | RegExp, replaceValue: string): string;
//   replace(searchValue: string | RegExp,
//           replacer: (substring: string, ...args: any[]) => string): string;
//   replaceAll(searchValue: string | RegExp, replaceValue: string): string;
//   replaceAll(searchValue: string | RegExp,
//              replacer: (substring: string, ...args: any[]) => string): string;
// }

// Type-safe replacement function
function safeReplace(
  input: string,
  pattern: string | RegExp,
  replacement: string
): string {
  return input.replace(pattern, replacement);
}

// Type-safe callback replacement
function mapReplace(
  input: string,
  pattern: RegExp,
  fn: (match: string, ...groups: string[]) => string
): string {
  return input.replace(pattern, fn);
}

// Usage examples
const result1: string = safeReplace('hello world', /world/g, 'TypeScript');
console.log(result1); // "hello TypeScript"

const result2: string = mapReplace('3 + 5 = 8', /\d+/g, (match) => {
  return String(Number(match) * 10);
});
console.log(result2); // "30 + 50 = 80"

// Generic template literal type (TypeScript 4.1+)
type Replace<
  S extends string,
  From extends string,
  To extends string
> = S extends `${infer Before}${From}${infer After}`
  ? `${Before}${To}${After}`
  : S;

// Compile-time string replacement:
type Result = Replace<'Hello World', 'World', 'TS'>;
// type Result = "Hello TS"

10. Frequently Asked Questions

What is the difference between replace() and replaceAll() in JavaScript?

replace() with a string argument replaces only the first occurrence. replaceAll() replaces every occurrence. When using a regex with the /g flag, both methods produce the same result. replaceAll() was introduced in ES2021 and requires the /g flag when given a regex argument.

How do I use capture groups in JavaScript replace?

Wrap part of your regex in parentheses to create a capture group: /(\w+)@(\w+)/. In the replacement string, use $1 for the first group, $2 for the second, and so on. The full match is available as $&. In a callback function, capture groups are passed as the second, third, etc. parameters.

Can I use a function as the replacement in replace()?

Yes. Pass a function as the second argument: str.replace(/pattern/g, (match, p1, p2, offset, string) => { ... }). The function is called for every match and its return value is used as the replacement. This is the most powerful form of replace() and is essential for dynamic transformations.

Why does replaceAll() throw a TypeError with regex?

replaceAll() requires the /g (global) flag when given a regex argument. If you pass a regex without /g, JavaScript throws a TypeError: "String.prototype.replaceAll called with a non-global RegExp argument". This is by design to prevent accidental single-replacement behavior.

How do I replace a string in JavaScript without regex?

Use replaceAll(searchString, newString) for replacing all occurrences of a literal string, or split(search).join(replacement) as a fallback for older environments. For a single replacement, use replace(searchString, newString). These methods do not interpret special regex characters, so they are safer for user-supplied input.

Bookmark this guide for your next string manipulation task. For interactive regex testing, try our tool below.

Try the Regex Tester β†’

𝕏 Twitterin LinkedIn
Was dit nuttig?

Blijf op de hoogte

Ontvang wekelijkse dev-tips en nieuwe tools.

Geen spam. Altijd opzegbaar.

Try These Related Tools

.*Regex TesterJSJS/HTML FormatterR+Regex Generator

Related Articles

Regex Cheat Sheet: Complete referentie voor reguliere expressies

Uitgebreid regex-cheatsheet: syntaxis, tekenklassen, kwantoren, lookaheads en kant-en-klare patronen.

20 Regex-patronen die Elke Ontwikkelaar Nodig Heeft: Copy-Paste Voorbeelden

Gecureerde collectie van 20 beproefde regex-patronen voor e-mail, URL, telefoon, wachtwoord, IP en meer.