Skip to content
Laviyx Learn

Try

JavaScript course menu

JavaScript Regular Expressions (Regex): Patterns, Flags, Groups and Methods

Learn regular expressions in JavaScript: creating patterns, test, match, matchAll, replace and split, character classes, quantifiers, anchors, flags (g, i, m, s, u), capturing and named groups, lookaheads, and practical validation examples.

Advanced8 min readUpdated
On this page

A regular expression (regex) is a pattern that describes text. With one short pattern you can check whether a string looks like a PIN code, find every hashtag in a post, or reformat dates. Regexes look cryptic at first, but they are built from a small number of pieces.

Creating and testing#

JavaScript
const pattern = /cat/;

console.log(pattern.test("The cat sat"));
console.log(pattern.test("The dog sat"));
console.log(/cat/i.test("CAT"));
Output
true
false
true
  • A regex literal is written between slashes: /cat/.
  • regex.test(string) returns true if the pattern appears anywhere in the string.
  • Letters after the closing slash are flags; i means ignore case.

You can also build a regex from a string with new RegExp("cat", "i"), which is useful when the pattern comes from a variable.

Character classes#

PatternMatches
.Any character except a line break
\dA digit (0 to 9)
\wA word character: letter, digit or underscore
\sWhitespace: space, tab, line break
\D, \W, \SThe opposite of the above
[aeiou]Any one of the listed characters
[a-z], [0-9A-F]A character in a range
[^0-9]Any character not listed

To match a character with a special meaning (such as ., ?, +, ( or /) literally, escape it with a backslash: \. matches a full stop.

Quantifiers#

QuantifierMeans
*0 or more
+1 or more
?0 or 1 (optional)
{3}Exactly 3
{2,4}Between 2 and 4
{2,}2 or more
JavaScript
console.log(/colou?r/.test("color"), /colou?r/.test("colour"));
console.log(/\d{3}-\d{4}/.test("call 555-1234 now"));
console.log("Ordered 12 pens and 150 sheets".match(/\d+/g));
Output
true true
true
[ '12', '150' ]

Anchors: matching the whole string#

^ matches the start and $ the end of the string. Without them, a pattern can match anywhere inside the text, which is a classic validation bug:

JavaScript
const pin = /^\d{6}$/;
console.log(pin.test("500001"));
console.log(pin.test("PIN 500001"));
console.log(/\d{6}/.test("PIN 500001 or more"));
Output
true
false
true

\b matches a word boundary: /\bcat\b/ finds "cat" but not "category".

Flags#

FlagMeaning
gGlobal: find all matches, not just the first
iIgnore case
mMultiline: ^ and $ match at line starts and ends
sDot-all: . also matches line breaks
uUnicode: treat emoji and other characters correctly

Groups#

Parentheses create capturing groups, which extract parts of a match. Named groups ((?<name>...)) are easier to read:

JavaScript
const date = "2026-10-24";

const [, year, month, day] = date.match(/(\d{4})-(\d{2})-(\d{2})/);
console.log(day, month, year);

const { groups } = date.match(/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/);
console.log(`${groups.d}/${groups.m}/${groups.y}`);
Output
24 10 2026
24/10/2026

(?:...) groups without capturing, and a|b means "a or b": /^(?:jpg|png|webp)$/.

Methods#

MethodReturns
regex.test(str)true or false
str.match(regex)Without g: the first match with its groups. With g: an array of all matches. null if none
str.matchAll(regex)An iterator of every match with its groups (needs g)
str.replace(regex, replacement)A new string; with g, every match is replaced
str.split(regex)An array of the parts between matches
str.search(regex)The index of the first match, or -1
JavaScript
const post = "Learning #JavaScript and #CSS today! #webdev";

console.log(post.match(/#\w+/g));

for (const m of post.matchAll(/#(\w+)/g)) {
  console.log(`tag "${m[1]}" at index ${m.index}`);
}

console.log("2026-10-24".replace(/(\d+)-(\d+)-(\d+)/, "$3.$2.$1"));
console.log("a, b;c   d".split(/[,;\s]+/));
console.log("hello world".replace(/\b\w/g, (letter) => letter.toUpperCase()));
Output
[ '#JavaScript', '#CSS', '#webdev' ]
tag "JavaScript" at index 9
tag "CSS" at index 25
tag "webdev" at index 37
24.10.2026
[ 'a', 'b', 'c', 'd' ]
Hello World

In a replacement string, $1, $2 (or $<name>) insert captured groups. A replacement function receives each match and returns the new text.

Lookahead#

A lookahead (?=...) checks that something follows, without including it in the match. Several lookaheads at the start can check independent rules, as in this password check:

JavaScript
const strong = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/;

for (const pwd of ["password", "Password1", "Pa1"]) {
  console.log(pwd, strong.test(pwd));
}
Output
password false
Password1 true
Pa1 false

For user-facing validation, separate simple checks with clear messages are usually friendlier than one large pattern (Handling Forms).

Practical patterns#

JavaScript
const patterns = {
  indianMobile: /^[6-9]\d{9}$/,
  pinCode: /^\d{6}$/,
  hexColour: /^#(?:[0-9a-f]{3}){1,2}$/i,
  simpleEmail: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
};

console.log(patterns.indianMobile.test("9876543210"), patterns.indianMobile.test("1234567890"));
console.log(patterns.hexColour.test("#2F5FE0"), patterns.hexColour.test("#12345"));
console.log(patterns.simpleEmail.test("asha@example.com"), patterns.simpleEmail.test("asha@"));
Output
true false
true false
true false

No regex can fully validate an email address; a simple shape check plus a confirmation email is the practical approach.

Tips#

  • Build and test patterns on a site such as regex101.com, which explains every part.
  • Add comments or name your patterns: const PIN_CODE = /^\d{6}$/.
  • Beware of a regex with the g flag reused with test(): it remembers its lastIndex between calls, which can give alternating results. Create the regex inside the function, or avoid g with test.

Practice#

Practice exercise

From the text "Contact: asha@example.com, ravi.k@mail.co.in or call 98765 43210", extract all email addresses, and extract the phone number with its space removed.

Show solution
JavaScript
const text = "Contact: asha@example.com, ravi.k@mail.co.in or call 98765 43210";

const emails = text.match(/[\w.]+@[\w.]+\w/g);
const phone = text.match(/\d{5}\s?\d{5}/)[0].replace(/\s/g, "");

console.log(emails);
console.log(phone);
Output
[ 'asha@example.com', 'ravi.k@mail.co.in' ]
9876543210

The email pattern ends with \w so that the trailing comma and full stop are not included.

Key takeaway#

Finished this lesson?