Skip to content

Step 1 of 5 · Reading · ~3 min

Learn

Generators and Regex

Regular Expressions

A regular expression (regex) describes a pattern of text. You use one to test whether text fits a pattern, to pull pieces out of it, or to rewrite it. By the end of this lesson you can read and write the common building blocks, use capture groups (including named ones), and avoid the traps around the g flag.

Writing a pattern

A regex literal sits between slashes, with optional flags after the closing slash. new RegExp("text", "flags") builds one from a string, in which case every backslash must be doubled.

PieceMatches
abcexactly those characters
.any one character except a newline
\d \w \sa digit, a word character (letter, digit, _), a whitespace character
[aeiou], [^0-9], [a-f]one character from the set, not from the set, in a range
^ $start and end of the text (of each line with the m flag)
* + ? {2,4}0 or more, 1 or more, 0 or 1, between 2 and 4 of the thing before
a|ba or b
(...) (?:...)a capture group, a group that is not captured
\. \(a literal dot, a literal parenthesis: escape characters that have meaning

The most common bug is an unescaped .: /1.5/ also matches 1x5.

By default quantifiers are greedy (take as much as possible); add ? to make them lazy:

javascript

Flags

i ignores case. g finds every match instead of stopping at the first. m lets ^ and $ match at line breaks. s lets . match a newline. u turns on full Unicode handling.

Testing and finding

javascript

match with g returns all matched strings, or null when nothing matches, so .length on the result can crash. Without g, match returns details about the first match only: [0] is the matched text, [1], [2], ... the capture groups, and .index the position.

Capture groups

Parentheses capture part of a match, and named groups ((?<name>...)) let you read the pieces by name:

javascript

In replace, $1, $2 (or $<name>) in the replacement string refer to groups, and a function can compute the replacement:

javascript

To walk all matches with their groups, use text.matchAll(regex). It returns an iterator of full match objects, one per match, and requires the g flag (without it, it throws a TypeError):

javascript

The lastIndex trap

A regex with g remembers where its last match ended, in lastIndex. Calling test or exec again continues from there:

javascript

Keep g regexes for match, matchAll and replace, or drop the g when you only call test.

Common mistakes

  • Forgetting g, so only the first match is replaced or returned.
  • Unescaped ., (, + or ? that you meant literally.
  • Using ^ and $ loosely: /\d{3}/ matches inside 1234, while /^\d{3}$/ does not.
  • Reading .length of a match(/x/g) result that is null.
  • Reusing a g regex with test and getting alternating answers.
  • Using a regex for nested structures such as HTML. It will eventually fail.

Your exercise

Write one pattern and one loop to pull structured pieces out of free text. The starter prints whatever your function returns.

Up nextSet, Map, and the Iteration ProtocolsCollections and Property Descriptors

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…