JavaScript Regex Methods: test(), exec(), match(), and replace()

Regular expressions become much more useful when you know how JavaScript methods use them to check, find, and change text. This article explains the four core regex methods you will use most often: test(), exec(), match(), and replace().

Quick answer: Use test() for a true/false check, exec() when you need match details and capture groups, match() to get matches from a string, and replace() to change matched text.

Difficulty: Beginner

You'll understand this better if you know: basic strings, regular expression syntax, and how JavaScript methods return values.

1. What Is JavaScript Regex Methods?

JavaScript regular expression methods are built-in functions that let you apply a RegExp pattern to text. Some methods return a yes-or-no answer, some return matched text, and some return a modified string.

These methods solve a common problem: text rarely comes in a perfectly structured form, so you need a flexible way to detect and handle patterns like email addresses, numbers, tags, or file names.

2. Why JavaScript Regex Methods Matter

Regex methods help you validate input, extract data, transform text, and search through content without writing lots of manual string logic. They are especially useful when a rule is easier to describe as a pattern than as many separate conditions.

You will use them in form validation, log parsing, data cleaning, search features, and text formatting. They also appear in interviews because they test both pattern thinking and API knowledge.

3. Basic Syntax or Core Idea

Regex pattern and method call

Most regex methods use either a RegExp object or a regex literal. The pattern is written between slashes, and flags change how the regex behaves.

const pattern = /hello/i // case-insensitive

The i flag makes the match ignore letter case. A method like test() or exec() is then called on the regex object.

Using the methods on a string

Some methods live on the regex object, while others live on the string. That difference matters because it affects the return value and the way you write the code.

const text = "Hello world";
const regex = /hello/i;

regex.test(text);      // true
regex.exec(text);      // detailed match array
text.match(regex);     // matches found in the string
text.replace(regex, "Hi"); // "Hi world"

This is the simplest way to remember the API: regex methods answer questions about a pattern, while string methods operate on text using a pattern.

4. Step-by-Step Examples

Example 1: Checking a pattern with test()

Use test() when you only need a boolean result. This is the fastest way to ask whether a match exists.

const hasNumber = /\d+/test("Order 42");

console.log(hasNumber); // true

This example checks whether the string contains one or more digits. The result is only true or false.

Example 2: Getting match details with exec()

Use exec() when you want more than a yes-or-no answer. It returns the matched text, the index of the match, and any capture groups.

const regex = /(\w+)@(\w+\.com)/;
const result = regex.exec("Email: [email protected]");

console.log(result[0]); // [email protected]
console.log(result[1]); // sam
console.log(result[2]); // example.com

The first item is the full match, and later items are capture groups from parentheses in the pattern.

Example 3: Finding matches with match()

Use match() when you want to search a string for a regex pattern. The result changes depending on whether the regex uses the global flag.

const text = "red blue red";

text.match(/red/);    // ["red", index: 0, input: "red blue red", groups: undefined]
text.match(/red/g);   // ["red", "red"]

Without g, match() gives the first match plus extra details. With g, it returns only the matching strings.

Example 4: Replacing text with replace()

Use replace() when you want a new string with parts changed. It does not modify the original string because strings are immutable.

const message = "price: 100";
const updated = message.replace(/\d+/, "120");

console.log(message); // price: 100
console.log(updated); // price: 120

This example shows the original string is unchanged, while the returned string contains the replacement.

Example 5: Using capture groups in replace()

You can use capture groups to rearrange matched parts of a string. This is common when formatting names, dates, or identifiers.

const name = "Doe, Jane";
const formatted = name.replace(/(\w+),\s(\w+)/, "$2 $1");

console.log(formatted); // Jane Doe

The replacement string uses $1 and $2 to insert capture groups in a new order.

5. Practical Use Cases

6. Common Mistakes

Mistake 1: Expecting match() to always return the same shape

match() changes its return value depending on the presence of the global flag. That surprises many developers who expect capture groups in every case.

Problem: With the global flag, match() returns an array of strings and does not include capture groups or index details.

const text = "a1 b2";
const result = text.match(/(\w)(\d)/g);

console.log(result[1][1]); // TypeError

Fix: Use exec() when you need capture groups, or use matchAll() if you need every match with details.

const regex = /(\w)(\d)/;
const result = regex.exec("a1 b2");

console.log(result[1]); // a
console.log(result[2]); // 1

The corrected version works because exec() always returns match details for one match at a time.

Mistake 2: Forgetting that test() can be stateful with g or y

When a regex uses the global or sticky flag, repeated calls to test() can produce alternating results because the method advances lastIndex.

Problem: The second call may fail even though the text still matches, because the regex remembers where the last search ended.

const regex = /\d+/g;

console.log(regex.test("42")); // true
console.log(regex.test("42")); // false

Fix: Remove g when you only want a boolean check, or reset lastIndex before reusing the regex.

const regex = /\d+/;

console.log(regex.test("42")); // true
console.log(regex.test("42")); // true

The corrected version works because a non-global regex does not keep search state between calls.

Mistake 3: Expecting replace() to change the original string

Strings in JavaScript are immutable, so replace() returns a new string instead of changing the old one.

Problem: The original variable still contains the old text if you do not store the return value.

let text = "hello world";
text.replace(/world/, "JavaScript");

console.log(text); // hello world

Fix: Assign the return value back to a variable when you want to keep the updated text.

let text = "hello world";
text = text.replace(/world/, "JavaScript");

console.log(text); // hello JavaScript

The corrected version works because you keep the new string that replace() returns.

7. Best Practices

Practice 1: Use test() for validation and booleans

If you only need to know whether a pattern exists, test() is clearer than extracting match data you will never use.

const isValidZip = /^\d{5}$/test("12345");

This keeps validation code short and easy to read.

Practice 2: Use exec() when you need capture groups

Capture groups are often the reason to use regex in the first place. exec() makes those groups easy to access.

const dateRegex = /(\d{4})-(\d{2})-(\d{2})/;
const match = dateRegex.exec("2026-06-28");

This is better than trying to reconstruct the pieces manually from the full match.

Practice 3: Use replace() with a callback for dynamic changes

When replacement text depends on the match, use a function instead of a plain string. This avoids awkward string concatenation and makes the logic easier to follow.

const text = "apples 2, oranges 3";
const result = text.replace(/(\d+)/g, (match) => String(Number(match) * 2));

The callback version is useful for formatting, counting, or conditional replacements.

8. Limitations and Edge Cases

9. Practical Mini Project

Let’s build a small text cleaner that checks for digits, extracts a code, and normalizes spacing. This shows how the methods work together in one realistic task.

const input = "  ticket: AB-1234   ";
const hasDigits = /\d+/test(input);
const codeMatch = /([A-Z]{2}-\d{4})/exec(input);
const cleaned = input.trim().replace(/\s+/g, " ");

console.log(hasDigits); // true
console.log(codeMatch[1]); // AB-1234
console.log(cleaned); // ticket: AB-1234

This mini project uses test() for validation, exec() for extraction, and replace() for cleanup.

10. Key Points

11. Practice Exercise

Expected output: The function should return true for strings like "Order 456 shipped", extract 456, and return "Order [hidden] shipped".

Hint: A pattern like /\d{3}/ is enough for the exercise.

Solution:

function handleOrderText(text) {
  const regex = /\d{3}/;
  const isValid = regex.test(text);
  const match = regex.exec(text);
  const masked = text.replace(regex, "[hidden]");

  return { isValid, code: match ? match[0] : null, masked };
}

console.log(handleOrderText("Order 456 shipped"));

This solution shows the same pattern used in three different ways: checking, extracting, and replacing.

12. Final Summary

JavaScript regex methods give you four essential tools for working with patterned text. test() answers whether a match exists, exec() gives detailed match data, match() searches a string for matches, and replace() creates updated text.

Once you understand how return values change with flags like g and how capture groups work, these methods become reliable building blocks for validation, extraction, and text cleanup. A good next step is to practice with real strings from forms, logs, or filenames so you can see which method fits each task best.