Grokking Advanced JavaScript
Vote

0% completed

​

Regular Expression Syntax and Examples

Literal and special characters

Character classes

Shorthand classes

Quantifiers

Anchors

Groups and alternation

Flags

Building the email pattern

A phone number pattern

A regular expression literal is a pattern written between two forward slashes, followed by optional letters called flags that change how the pattern is applied.

const pattern = /pattern/flags;

For example, /book/i is the pattern book with the flag i. You can call the RegExp methods test() and exec() on a pattern, and you can pass a pattern to the string methods match(), replace(), and split(). This lesson explains the pieces a pattern is made of, and then uses them to build the email pattern from the previous lesson one piece at a time.

Literal and special characters

Most characters in a pattern match themselves. The pattern /book/ matches the four letters b, o, o, k in that order, anywhere in the text. A few characters have a special meaning instead:

. * + ? ^ $ { } ( ) | [ ] \ /

To match one of these characters literally, put a backslash before it. This is called escaping the character. The dot is the one that causes the most mistakes: /1.5/ matches "105", because an unescaped dot matches any character, while /1\.5/ matches only the text 1.5.

Character classes

Square brackets describe a character class: a set of characters, of which exactly one must appear at that position.

PatternMatches one character that is
[abc]a, b, or c
[^abc]anything except a, b, or c
[0-9]a digit from 0 to 9
[a-z]a lowercase letter from a to z
[A-Z]an uppercase letter from A to Z
[a-zA-Z]any lowercase or uppercase letter
[._-]a dot, an underscore, or a hyphen

A hyphen between two characters means a range, so a literal hyphen is written at the start or the end of the class, as in [._-]. Inside the brackets, a dot means a plain dot.

Avoid the range [A-z]. It looks like "all letters", but a range follows the order of character codes, and six other characters come between Z and a: [, \, ], ^, _, and the backtick. As a result, /[A-z]/.test("_") returns true. Write [a-zA-Z] when you mean letters.

Shorthand classes

Some character classes are used so often that they have a short name.

PatternMatches
.any one character except a line break
\da digit, the same as [0-9]
\Dany character that is not a digit
\wa word character, the same as [a-zA-Z0-9_]
\Wany character that is not a word character
\sa whitespace character, such as a space, a tab, or a line break
\Sany character that is not whitespace

\w matches only unaccented English letters, digits, and the underscore, so /^\w+$/.test("José") returns false. Keep this in mind before you use \w to check names.

Quantifiers

A quantifier says how many times the item before it may repeat. The item is the single character, character class, or group directly to its left.

QuantifierThe item before it appears
+one or more times
*zero or more times
?zero or one time, which makes the item optional
{n}exactly n times
{n,}n or more times
{n,m}at least n and at most m times

For example, /colou?r/ matches both color and colour, because ? makes the u optional. In /\d{3}/, the quantifier applies to \d, so the pattern means three digits in a row.

Anchors

An anchor matches a position in the text instead of a character.

AnchorMatches
^the start of the text, or the start of each line with the m flag
$the end of the text, or the end of each line with the m flag
\ba word boundary: a position between a word character and a non-word character, or between a word character and the start or end of the text
\Bany position that is not a word boundary

Anchors decide whether the pattern must match the whole text or just a part of it. Without anchors, /\d{2,4}/.test("12345") returns true, because the pattern finds 1234 inside the longer text. With anchors, /^\d{2,4}$/ accepts only text that is two to four digits and nothing else. A validation pattern almost always needs both ^ and $.

Groups and alternation

Parentheses create a group, which treats several characters as one item. A quantifier after a group repeats the whole group: /^(ha)+$/ matches hahaha, while /^ha+$/ matches haaa. The vertical bar | means "or", so /\.(com|org|net)$/ matches text that ends in .com, .org, or .net.

A group also captures the text it matched. The string method match() returns the whole match first and then the text of each group, in the order of their opening parentheses.

Javascript
Javascript

. . . .
ann.lee@example.com ann.lee example.com com null

When the text does not match, match() returns null, as the last line shows for an address that ends in .io. With the g flag, match() behaves differently: it returns an array of every full match and leaves out the groups.

Flags

Flags are written after the closing slash, in any order, and they change how the whole pattern is applied.

FlagEffect
gglobal: find every match instead of stopping after the first one
iignore case: treat uppercase and lowercase letters as equal
mmultiline: make ^ and $ match at the start and end of each line
sdot all: make . match line breaks too

For example, /^.$/.test("\n") returns false, and /^.$/s.test("\n") returns true. JavaScript has four more flags, u, v, y, and d, for full Unicode support and special search modes; this chapter does not need them.

Building the email pattern

The email pattern from the previous lesson is now readable piece by piece.

const emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
Each part of the email pattern lined up with the part of ann.lee@example.com that it matches.
Each part of the email pattern lined up with the part of ann.lee@example.com that it matches.

The diagram lines up each piece of the pattern with the part of the address it matches. Read it from left to right:

  1. ^ requires the match to begin at the start of the text.
  2. [a-zA-Z0-9._-]+ matches the name before the @: one or more letters, digits, dots, underscores, or hyphens. Here it matches ann.lee.
  3. @ matches the @ sign itself.
  4. [a-zA-Z0-9.-]+ matches the domain name: one or more letters, digits, dots, or hyphens. Here it matches example.
  5. \. matches one literal dot. Without the backslash, it would match any character.
  6. [a-zA-Z]{2,6} matches the ending of two to six letters. Here it matches com.
  7. $ requires the match to end at the end of the text, so nothing may follow the ending.

The program below tests the pattern with five addresses.

Javascript
Javascript

. . . .
ann.lee@example.com true ann.lee@example false ann.lee@@example.com false Ann_Lee-2@mail.example.org true ann.lee@example.com. false

The second address fails at step 5, because no dot follows the domain name. The third fails at step 4, because the second @ is not allowed in the domain part. The last one fails because the text ends with a dot. Step 6 needs letters directly before the end of the text, and step 7 allows nothing after them, so the final dot cannot be part of a match.

A phone number pattern

A pattern for a US phone number in the form 555-123-4567 uses the same pieces.

const phonePattern = /^\d{3}-\d{3}-\d{4}$/;

It matches exactly three digits at the start, a hyphen, three more digits, another hyphen, and exactly four digits at the end. If the numbers may use dots or spaces as separators, replace each hyphen with the character class [-. ].

Javascript
Javascript

. . . .
true false false true true

The strict pattern rejects the dotted number and the number with five digits at the end. The flexible pattern accepts both separators, because each [-. ] matches one hyphen, dot, or space.

Reading Progress

0%


Vote for new content

On This Page

Literal and special characters

Character classes

Shorthand classes

Quantifiers

Anchors

Groups and alternation

Flags

Building the email pattern

A phone number pattern