Regex

Cheat sheet

JavaScript (ECMAScript) regular expression syntax, as supported by current browsers and Node.js. Ready-made patterns ↓

Characters

.Any character except line breaks (with the s flag: any character)
\d \DA digit 0–9 / anything but a digit
\w \WA word character [A-Za-z0-9_] / anything else
\s \SWhitespace (space, tab, line breaks, Unicode spaces) / anything else
\t \n \r \v \fTab, newline, carriage return, vertical tab, form feed
\0The NUL character
\xhhCharacter by 2-digit hex code, e.g. \x41 is A
\uhhhhCharacter by 4-digit hex code, e.g. é is é
\u{h…}Any code point, e.g. \u{1F600} (u or v flag)
\cXControl character, e.g. \cJ is a newline
\. \* \\ \/Escape a special character: \ ^ $ . | ? * + ( ) [ ] { } /

Character classes

[abc]One of a, b or c
[^abc]Any character except a, b or c
[a-z0-9]A range: a to z or 0 to 9
[\w.-]Classes can hold escapes; a - at the start or end is literal
[^]Any character, including line breaks
[\b]A backspace character (only inside a class)
\p{L} \p{Lu}A letter / an uppercase letter, by Unicode property (u or v flag)
\p{Script=Greek}A character from a Unicode script (u or v flag)
\P{…}A character without the property (u or v flag)
[\p{L}--[a-z]]Difference: letters except a–z (v flag)
[\w&&\p{ASCII}]Intersection: in both sets (v flag)
[\q{abc|d}]A class that also matches whole strings (v flag)

Anchors and boundaries

^Start of the text (with the m flag: start of a line)
$End of the text (with the m flag: end of a line)
\bWord boundary: between \w and \W, or at the start or end
\BNot a word boundary

Quantifiers

*Zero or more times
+One or more times
?Optional: zero or one time
{n}Exactly n times
{n,}n or more times
{n,m}Between n and m times
*? +? ?? {n,m}?Lazy: as few times as possible (the default is greedy, as many as possible)

Groups, lookaround and alternation

(…)Capturing group, numbered from 1 by its opening parenthesis
(?<name>…)Named capturing group
(?:…)Non-capturing group
a|bAlternation: a or b (lowest precedence; group it to limit it)
(?=…)Lookahead: followed by …
(?!…)Negative lookahead: not followed by …
(?<=…)Lookbehind: preceded by …
(?<!…)Negative lookbehind: not preceded by …
(?i:…) (?-i:…)Turn flags i, m or s on or off inside the group (newer browsers)

Backreferences

\1 \2 …The same text that group 1, 2 … matched
\k<name>The same text that the named group matched

Flags

gglobal: find all matches, not just the first
iignore case
mmultiline: ^ and $ match at every line
sdotAll: . also matches line breaks
uunicode: code points, \p{…}, \u{…}, stricter syntax
vunicodeSets: like u, plus set operations and \q{…} (not together with u)
ysticky: match only at lastIndex
dindices: record start and end of each group (match.indices)

Replacement string

$1 $2 …Text of group 1, 2 …
$<name>Text of a named group
$&The whole match
$`The text before the match
$'The text after the match
$$A literal $

In code

re.test(str)true if there is a match
str.match(re)Without g: the first match with groups. With g: an array of all matched texts
str.matchAll(re)Iterator over every match with its groups (needs g)
re.exec(str)Next match; with g or y it continues from re.lastIndex
str.replace(re, s)Replace the first match, or all with g; s can be a function
str.replaceAll(re, s)Replace all matches (needs g)
str.split(re)Split at matches; captured groups are included in the result
new RegExp(src, flags)Build a regex from a string (escape backslashes in string literals)

Ready-made patterns

Each one opens in the tester with sample text. They are practical, not perfect validators.

Email address (rough)

Good for finding addresses in text. Real address syntax is far looser; to validate, send an email.

/[\w.+-]+@[\w-]+(?:\.[\w-]+)+/g

IPv4 address

Four numbers 0–255 separated by dots.

/\b(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\b/g

IPv6 address

Full and :: compressed forms, one address per line. No zone IDs or embedded IPv4.

/^(?:(?:[\da-f]{1,4}:){7}[\da-f]{1,4}|(?:[\da-f]{1,4}:){1,7}:|(?:[\da-f]{1,4}:){1,6}:[\da-f]{1,4}|(?:[\da-f]{1,4}:){1,5}(?::[\da-f]{1,4}){1,2}|(?:[\da-f]{1,4}:){1,4}(?::[\da-f]{1,4}){1,3}|(?:[\da-f]{1,4}:){1,3}(?::[\da-f]{1,4}){1,4}|(?:[\da-f]{1,4}:){1,2}(?::[\da-f]{1,4}){1,5}|[\da-f]{1,4}:(?::[\da-f]{1,4}){1,6}|:(?:(?::[\da-f]{1,4}){1,7}|:))$/gim

ISO 8601 date

YYYY-MM-DD with named groups. Does not check the number of days in a month.

/\b(?<year>\d{4})-(?<month>0[1-9]|1[0-2])-(?<day>0[1-9]|[12]\d|3[01])\b/g

Time (24-hour)

HH:MM with optional :SS.

/\b(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d)?\b/g

Hex colour

#rgb, #rgba, #rrggbb or #rrggbbaa.

/#(?:[\da-f]{8}|[\da-f]{6}|[\da-f]{3,4})\b/gi

UUID

Any version, either case.

/\b[\da-f]{8}-(?:[\da-f]{4}-){3}[\da-f]{12}\b/gi

URL (http and https)

Scheme, host, optional port and the rest up to whitespace. Trailing punctuation after a path is included.

/\bhttps?:\/\/[\w.-]+(?::\d+)?(?:[/?#]\S*)?/gi

MAC address

Six hex pairs with : or -; the backreference \1 makes every separator the same.

/\b[\da-f]{2}([:-])[\da-f]{2}(?:\1[\da-f]{2}){4}\b/gi

Semantic version

The semver.org pattern with named groups, one version per line.

/^(?<major>0|[1-9]\d*)\.(?<minor>0|[1-9]\d*)\.(?<patch>0|[1-9]\d*)(?:-(?<pre>(?:0|[1-9]\d*|\d*[a-z-][\da-z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-z-][\da-z-]*))*))?(?:\+(?<build>[\da-z-]+(?:\.[\da-z-]+)*))?$/gim

Croatian OIB

Exactly 11 digits. The last digit is a check digit (ISO 7064, MOD 11,10), which a regex cannot verify.

/\b\d{11}\b/g

Repeated word

A word followed by the same word, using a backreference.

/\b(\w+)\s+\1\b/gi

Trailing whitespace

Spaces and tabs at the end of each line. Replace with nothing to trim.

/[ \t]+$/gm