Skip to content
Educora
Advanced22 min21 / 27

Regular expressions

Search, validate and transform text with regular expressions: character classes, quantifiers, anchors, groups, flags and the `test`, `match`, `matchAll` and `replace` methods.

Check yourself
In this lesson you will learn
  • Read and write patterns with character classes, quantifiers and anchors
  • Use the flags g, i, m, u and the methods test, match, matchAll, replace, split
  • Extract data with capturing and named groups and avoid the typical traps

Checking that a phone number looks like +994 50 123 45 67, finding every hashtag in a post, turning 2026-09-27 into 27.09.2026 — with ordinary string methods each task takes a dozen lines. A regular expression (regex) describes a text pattern in a single line. It looks cryptic at first, but it is built from a small set of bricks — once you know them, everything becomes readable.

Creating a regex and the first methods

There are two ways to create a regex: the literal /pattern/flags, or new RegExp('pattern', 'flags') when the pattern is built at run time. The main methods: regex.test(str) returns true/false; str.match(regex) gives the first match (with g, all of them); str.replace(regex, replacement) replaces; str.split(regex) splits by the pattern.

JavaScript
const text = 'Order 15 arrived. Order 27 is late. Call 555.';

console.log(/late/.test(text));
console.log(/LATE/i.test(text));
console.log(text.match(/\d+/)[0]);
console.log(text.match(/\d+/g));
console.log(text.replace(/Order/g, 'Parcel'));
console.log('a1b22c333'.split(/\d+/));
▸ Expected output
true
true
15
[ '15', '27', '555' ]
Parcel 15 arrived. Parcel 27 is late. Call 555.
[ 'a', 'b', 'c', '' ]

The building blocks

PatternMeaning
.any character except a line break
\d \w \sa digit; a word character (Latin letter, digit, _); whitespace. Uppercase means the opposite: \D, \W, \S
[abc] [a-z] [^0-9]one character from a set; a range; a character not in the set
* + ?0 or more; 1 or more; 0 or 1
{3} {2,5}exactly 3 times; from 2 to 5 times
^ $ \bstart of the string; end; a word boundary
a|b ( ) (?<name> )or; a group; a named group
JavaScript
const patterns = {
  postcode: /^AZ\d{4}$/,
  phone: /^\+994 \d{2} \d{3} \d{2} \d{2}$/,
  username: /^[a-z][a-z0-9_]{2,15}$/,
};

const samples = {
  postcode: ['AZ1000', 'AZ100', 'az1000'],
  phone: ['+994 50 123 45 67', '+994501234567'],
  username: ['leyla_07', '7leyla', 'ab'],
};

for (const [name, regex] of Object.entries(patterns)) {
  const results = samples[name].map((value) => `${value}: ${regex.test(value)}`);
  console.log(`${name} -> ${results.join(', ')}`);
}
▸ Expected output
postcode -> AZ1000: true, AZ100: false, az1000: false
phone -> +994 50 123 45 67: true, +994501234567: false
username -> leyla_07: true, 7leyla: false, ab: false
+ is a special character, so we write \+ to match it literally. A username must start with a letter and be 3–16 characters long in total.

Flags

  • g — global: all matches (required for matchAll and for replaceAll with a regex);
  • i — ignore case;
  • m — multiline: ^ and $ mean the start and end of every line;
  • s — . also matches a line break;
  • u — Unicode: emoji and \p{L} (a letter of any alphabet) work correctly.
JavaScript
const words = 'Gəncə şəhəri';

console.log(words.match(/\w+/g));
console.log(words.match(/\p{L}+/gu));

const poem = 'first line\nsecond line\nthird line';
console.log(poem.match(/^\w+/gm));
▸ Expected output
[ 'G', 'nc', 'h', 'ri' ]
[ 'Gəncə', 'şəhəri' ]
[ 'first', 'second', 'third' ]
\w knows only the letters of the English alphabet, so letters outside it break the words apart. For Azerbaijani, Russian or Turkish text, use \p{L} with the u flag.

Groups and replacing

Parentheses capture parts of the match. match without g returns an array: [full match, group1, group2, ...], and named groups are in .groups. matchAll (which requires g) gives every match together with its groups. In replace, $1 and $<name> refer to groups, and a replacement function receives the match and the groups as arguments.

JavaScript
const date = '2026-09-27';
const match = date.match(/^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/);

console.log(match[1], match.groups.month, match.groups.day);
console.log(date.replace(/(\d{4})-(\d{2})-(\d{2})/, '$3.$2.$1'));

const post = 'Learning #javascript and #regex at #Educora';
const tags = [...post.matchAll(/#(\w+)/g)].map((m) => m[1].toLowerCase());
console.log(tags);

const prices = 'tea 2 AZN, bread 1 AZN';
console.log(prices.replace(/(\d+) AZN/g, (whole, amount) => `${amount * 2} AZN`));
▸ Expected output
2026 09 27
27.09.2026
[ 'javascript', 'regex', 'educora' ]
tea 4 AZN, bread 2 AZN
JavaScript
const html = '<b>bold</b> and <i>italic</i>';
console.log(html.match(/<.*>/)[0]);
console.log(html.match(/<.*?>/g));

const hasDigit = /\d/g;
console.log(hasDigit.test('a1'), hasDigit.test('a1'), hasDigit.test('a1'));

console.log('1.5'.match(/\d.\d/)[0], '1x5'.match(/\d.\d/)[0], /\d\.\d/.test('1x5'));
▸ Expected output
<b>bold</b> and <i>italic</i>
[ '<b>', '</b>', '<i>', '</i>' ]
true false true
1.5 1x5 false
Exercise

Write isStrongPassword(password): the password must be at least 8 characters long and contain at least one digit and one uppercase Latin letter. Use a separate regex and test for each rule.

Exercise · JavaScript
function isStrongPassword(password) {
  // 8+ characters, a digit, an uppercase letter
}

for (const password of ['secret', 'Secret123', 'secretpass1', 'SECRETPASS']) {
  console.log(`${password}: ${isStrongPassword(password)}`);
}
▸ Expected output
secret: false
Secret123: true
secretpass1: false
SECRETPASS: false
Exercise

Convert every DD.MM.YYYY date in the text to ISO format YYYY-MM-DD and print the result. Then print how many dates the text contains as Dates: N.

Exercise · JavaScript
const text = 'Exams: 05.06.2026 and 12.06.2026. Holidays from 20.06.2026.';

// 1) replace every DD.MM.YYYY with YYYY-MM-DD and print the text
// 2) print Dates: N
▸ Expected output
Exams: 2026-06-05 and 2026-06-12. Holidays from 2026-06-20.
Dates: 3

Key points

  • A regex is a text pattern: /pattern/flags or new RegExp(...).
  • Building blocks: classes (\d, \w, [a-z]), quantifiers (+, *, ?, {n,m}), anchors (^, $, \b), groups and |.
  • Flags: g all matches, i ignore case, m multiline, u Unicode (\p{L}).
  • test checks, match/matchAll extract, and replace transforms with $1, $<name> or a function.
  • Anchor validation patterns; beware of greedy .*, lastIndex with g and test, and unescaped special characters.

Check yourself

10 questions. Every correct answer earns XP.

1 / 10
Which string does /^\d{3}$/ match?