Regex Groups and String Methods
This section covers how to capture parts of matches and how to use regex with string methods.
Groups and Capturing
Capturing Groups
Parentheses create capturing groups:
const regex = /(\d{3})-(\d{4})/;
const match = "555-1234".match(regex);
console.log(match[0]); // "555-1234" (full match)
console.log(match[1]); // "555" (first group)
console.log(match[2]); // "1234" (second group)
Named Groups
const regex = /(?<area>\d{3})-(?<number>\d{4})/;
const match = "555-1234".match(regex);
console.log(match.groups.area); // "555"
console.log(match.groups.number); // "1234"
Non-Capturing Groups
Use (?:...) when you need grouping but do not need to capture:
// Captures "http" or "https"
const regex1 = /(https?):\/\//;
// Groups but doesn't capture
const regex2 = /(?:https?):\/\//;
Backreferences
Reference captured groups within the pattern:
// Match repeated words
const regex = /\b(\w+)\s+\1\b/;
console.log(regex.test("the the")); // true
console.log(regex.test("the cat")); // false
Alternation
Use | for “or”:
/cat|dog/.test("I have a cat"); // true
/cat|dog/.test("I have a dog"); // true
// Group alternatives
/(red|green|blue) car/.test("red car"); // true
Lookahead and Lookbehind
These are assertions. They check what comes before or after a position, and they do not consume any characters:
| Pattern | Name | Meaning |
|---|---|---|
(?=...) |
Positive lookahead | Followed by |
(?!...) |
Negative lookahead | Not followed by |
(?<=...) |
Positive lookbehind | Preceded by |
(?<!...) |
Negative lookbehind | Not preceded by |
// Password must have a digit
/(?=.*\d).{8,}/.test("password1"); // true
/(?=.*\d).{8,}/.test("password"); // false
// Match "foo" not followed by "bar"
/foo(?!bar)/.test("foobar"); // false
/foo(?!bar)/.test("foobaz"); // true
// Match number preceded by $
/(?<=\$)\d+/.exec("$100"); // ["100"]
RegExp and String Methods
Testing for Matches with RegExp.prototype.test()
Returns a boolean:
/\d+/.test("abc123"); // true
Finding Matches with match()
Returns different output depending on the g flag:
"hello world".match(/\w+/); // ["hello", index: 0, ...]
"hello world".match(/\w+/g); // ["hello", "world"]
Iterating All Matches with matchAll()
Returns an iterator of all matches with groups. If you pass a regex, it must have the g flag:
const regex = /(\w+)@(\w+)/g;
const text = "foo@bar baz@qux";
for (const match of text.matchAll(regex)) {
console.log(match[0], match[1], match[2]);
}
// "foo@bar" "foo" "bar"
// "baz@qux" "baz" "qux"
Finding Position with search()
Returns the index of the first match:
"hello world".search(/wo/); // 6
"hello world".search(/xyz/); // -1
Replacing Matches with replace()
Replace matched text:
"hello world".replace(/world/, "JavaScript");
// "hello JavaScript"
// With capturing groups
"John Smith".replace(/(\w+) (\w+)/, "$2, $1");
// "Smith, John"
// With function
"hello".replace(/./g, (char) => char.toUpperCase());
// "HELLO"
Replacing All Occurrences with replaceAll()
If the pattern is a regex, it must include the g flag:
"a-b-c".replaceAll("-", "_"); // "a_b_c"
"a-b-c".replaceAll(/-/g, "_"); // "a_b_c"
Splitting Strings with split()
Split a string by a pattern:
"a, b, c".split(/,\s*/); // ["a", "b", "c"]