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.
- test() checks whether a pattern exists in a string.
- exec() returns detailed match information from a pattern.
- match() finds matches in a string.
- replace() swaps matched text with new text.
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-insensitiveThe 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); // trueThis 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.comThe 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: 120This 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 DoeThe replacement string uses $1 and $2 to insert capture groups in a new order.
5. Practical Use Cases
- Checking whether a password contains at least one digit or special character.
- Extracting file extensions from names like report.pdf.
- Finding all tags or keywords in user-generated text.
- Replacing repeated spaces, punctuation, or formatting characters.
- Parsing log lines for timestamps, status codes, or IDs.
- Reformatting data such as dates or names before display.
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]); // TypeErrorFix: 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]); // 1The 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")); // falseFix: 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")); // trueThe 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 worldFix: 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 JavaScriptThe 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
- match() with g does not return capture groups, which is a common source of confusion.
- test() and exec() can be affected by lastIndex when the regex uses g or y.
- replace() only changes the first match unless you use the global flag.
- exec() returns null when there is no match, so you must check before reading array items.
- Unicode text can be tricky if your pattern does not account for emoji, accents, or multi-byte characters.
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-1234This mini project uses test() for validation, exec() for extraction, and replace() for cleanup.
10. Key Points
- Use test() when you only need a boolean result.
- Use exec() when you need the matched text and capture groups.
- Use match() for searching strings, especially when you want a simple match result.
- Use replace() to return a new string with text changed.
- Remember that flags like g, i, and y can change method behavior.
11. Practice Exercise
- Write a function that checks whether a string contains a valid 3-digit number.
- Use exec() to extract the number from a sentence.
- Use replace() to replace that number with [hidden].
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.