Skip to content

Intermediate · Map, Set, iterators, generators and regular expressions · topic 35 of 61 · 30 min

Regular expressions in practice

Explanation

Groups (…) capture parts of a match, and named groups (?<year>…) give them readable names. replace can use captured parts ($1 or a function) to reformat text. Quantifiers are greedy by default; add ? to make them lazy. Escape special characters, use the u flag for Unicode, and beware patterns that backtrack forever.

Capturing groups

Round brackets group part of a pattern and also capture the text it matched, so you can use it later. Groups are numbered from 1 in the order of their opening bracket.

javascript
const m = '2026-10-19'.match(/(\d{4})-(\d{2})-(\d{2})/);
console.log(m[0]); // '2026-10-19' (the whole match)
console.log(m[1], m[2], m[3]); // '2026' '10' '19'

Named groups

javascript
const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const { year, month, day } = '2026-10-19'.match(re).groups;
console.log(`${day}/${month}/${year}`); // 19/10/2026
Named groups make long patterns readable and safe to change.

Replacing with captured parts

javascript
// $1, $2 … or $<name> refer to groups in the replacement string
console.log('2026-10-19'.replace(/(\d{4})-(\d{2})-(\d{2})/, '$3/$2/$1')); // '19/10/2026'

// a function gets the match and the groups and returns the replacement
const prices = 'tea 10, coffee 25';
console.log(prices.replace(/\d+/g, (n) => String(Math.round(n * 1.18)))); // 'tea 12, coffee 30'

Non-capturing groups and alternatives

(?:…) groups without capturing, which is useful with | or a quantifier when you do not need the text later: /(?:Mr|Ms|Dr)\.? [A-Z][a-z]+/ matches "Dr. Rao" or "Ms Iyer".

Greedy versus lazy

Quantifiers like * and + are greedy: they take as much text as possible and then give back only what is needed. Adding ? after them (*?, +?) makes them lazy: as little as possible.

javascript
const html = '<b>Price</b> and <b>Offer</b>';
console.log(html.match(/<b>.*<\/b>/)[0]);  // '<b>Price</b> and <b>Offer</b>' (greedy)
console.log(html.match(/<b>.*?<\/b>/)[0]); // '<b>Price</b>' (lazy)

Lookahead (in brief)

(?=…) checks that something follows, without including it in the match; (?!…) checks that it does NOT follow. A common use is password rules: /^(?=.*\d)(?=.*[A-Z]).{8,}$/ means "at least 8 characters, containing a digit and a capital letter".

Escaping special characters

These characters have special meaning: . * + ? ^ $ { } ( ) | [ ] \ /. To match them literally, put a backslash before them: \. matches a real dot. When you build a regex from user input with new RegExp, escape the input first, or a user typing "(" will break it. ES2025 added RegExp.escape for this; in older environments use text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').

Unicode and Indian languages

Without the u flag, some characters (like many emoji) count as two units, and \w only matches English letters. With u you can use Unicode property escapes: /\p{Script=Devanagari}+/u matches Hindi words.

javascript
console.log('नमस्ते India'.match(/\p{Script=Devanagari}+/u)[0]); // 'नमस्ते'
Careful: Some patterns, such as (a+)+$ on a long string of a's followed by a different character, make the engine try an exponential number of combinations and can freeze a server for minutes. This is called catastrophic backtracking, and attackers use it (ReDoS). Avoid nested quantifiers on the same characters, limit input length, and test patterns on long bad inputs.
Tip: Do not try to validate email addresses or URLs with a giant regex. Use a simple check (something@something.something) plus a confirmation email, or the URL constructor: new URL(text) throws for invalid URLs.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Regular expressions in practice · 1/6

Regex in practice

In this lesson you will use regular expressions for real text work: capturing, reformatting and cleaning.

Prefer a video by a teacher? Find free videos on “javascript regex capturing groups named groups replace lookahead” on YouTube ↗

In real life: Cleaning bank SMS messages

A personal-finance app reads bank SMS like "Rs.1,250.00 debited from A/c XX4321 on 19-10-26". A regex with named groups pulls out the amount, the last 4 digits and the date, so the app can build a spending report.

javascript
const sms = 'Rs.1,250.00 debited from A/c XX4321 on 19-10-26';
const re = /Rs\.(?<amount>[\d,]+\.\d{2}) debited from A\/c XX(?<last4>\d{4}) on (?<date>\d{2}-\d{2}-\d{2})/;
const { amount, last4, date } = sms.match(re).groups;
console.log(Number(amount.replaceAll(',', '')), last4, date); // 1250 '4321' '19-10-26'

Practice (0/3 done)

Task 1 · Code · Javascript

Write toIndianDate(iso) that turns "2026-10-19" into "19/10/2026" using replace with groups.

Task 2 · Code · Javascript

Write parseSms(sms) that extracts { amount, last4 } from messages like "Rs.1,250.00 debited from A/c XX4321". amount must be a number (1250), last4 a string. Return null if the message does not match.

Task 3 · Code · Javascript

Write escapeRegex(text) that puts a backslash before every special regex character, so new RegExp(escapeRegex(userText)) matches the text literally.

Quick quiz

Question 1

1.What is 'ab12'.match(/([a-z]+)(\d+)/)[2]?

Question 2

2.What does '<i>a</i><i>b</i>'.match(/<i>.*?<\/i>/)[0] give?

Question 3

3.How do you match a literal dot?

Question 4

4.What risk do patterns like (a+)+$ create?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What is 'ab12'.match(/([a-z]+)(\d+)/)[2]?

Answer: '12'

Group 2 is the second bracket: the digits.

What does '<i>a</i><i>b</i>'.match(/<i>.*?<\/i>/)[0] give?

Answer: '<i>a</i>'

.*? is lazy, so it stops at the first closing tag.

How do you match a literal dot?

Answer: \.

An unescaped dot matches any character.

What risk do patterns like (a+)+$ create?

Answer: Catastrophic backtracking that can freeze the program

Nested quantifiers can take exponential time on certain inputs (ReDoS).

What does \d+ match?Related

Answer: One or more digits

+ means one or more of the thing before it.

From Regular expressions: the basics

What does the pattern r"\d+" match?Related

Answer: One or more digits in a row

\d is a digit and + means one or more of it.

From JSON and regular expressions

A function calls its closure parameter many times, and the closure may change its captured state. Which bound fits?Related

Answer: FnMut

FnMut allows repeated calls that mutate state.

From Closures

What does a greedy algorithm do at each step?Related

Answer: Takes the choice that looks best now and never undoes it

Greedy commits to the locally best choice. Trying everything is brute force; storing sub-answers is dynamic programming.

From Greedy algorithms: the idea

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. This is the last topic of “Map, Set, iterators, generators and regular expressions”. The module exam comes next.
  2. Module 7 exam: Collections, iterators and regular expressions · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Asynchronous JavaScript. 61 topics left in the course before the final exam.

← Previous: Regular expressions: the basics