You need to pull every order number out of a 2 MB log file, or reject phone numbers that are obviously fake. You write a regex, it matches nothing, you add a backslash, now it matches everything. Sound familiar? Testing the pattern against real text as you write it saves most of that guesswork.
What regular expressions are
A regular expression (regex) is a small pattern that describes what some text should look like, such as "four digits, a dash, two digits". Developers use them to validate input, search text, pull out values and do find-and-replace. Every major language supports them, as do editors, command-line tools and many databases.
Regex is also famously hard to read. This pattern matches an IPv4 address such as 192.168.1.20, but you'd be forgiven for thinking a cat walked across the keyboard:
^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$The quickest way to understand a pattern like that, or to fix your own, is to run it against sample text and see exactly what it matches.
Regex basics
| Token | Matches |
|---|---|
. | Any single character except a line break |
\d | A digit, 0 to 9 |
\w | A word character: [A-Za-z0-9_] |
\s | Whitespace, including spaces, tabs and line breaks |
^ and $ | The start and end of the input (or of a line, with m) |
*, +, ? | 0 or more, 1 or more, 0 or 1 of the preceding item |
{n,m} | Between n and m of the preceding item |
[abc], [^abc] | Any character in the set, or not in the set |
(...) | A capture group |
| | Alternation: either side |
Common regex patterns
Email address
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$One or more allowed characters before the @, a domain, and a top-level domain of at least two letters. It covers ordinary addresses but not every address the standard allows, so use it as a sanity check and confirm addresses by sending an email.
URL
https?:\/\/[\w\-]+(\.[\w\-]+)+[\/\w\-._~:?#[\]@!$&'()*+,;=%]*Finds HTTP and HTTPS URLs in text, including paths and query strings. To validate a single URL in JavaScript, new URL(value) is more reliable.
US phone number
^(\+1)?[-.\s]?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$Matches formats such as (555) 123-4567, 555-123-4567 and +1 555 123 4567.
Regex flags
Flags change how the pattern is applied. In JavaScript:
| Flag | Name | Effect |
|---|---|---|
g | Global | Find all matches, not only the first |
i | Case insensitive | Ignore upper and lower case |
m | Multiline | ^ and $ match at the start and end of each line |
s | Dotall | . also matches line breaks |
u | Unicode | Treat the pattern as Unicode code points and enable \p{...} property escapes |
For example, /hello/gi finds every occurrence of “hello”, “Hello”, “HELLO” and so on.
Capture groups
Parentheses capture the part of the match they enclose, so you can pull out specific values:
Pattern: (\d{4})-(\d{2})-(\d{2})
Input: 2026-02-07
Group 1: 2026 (year)
Group 2: 02 (month)
Group 3: 07 (day)Named groups make the pattern easier to read and let code refer to groups by name:
const match = "2026-02-07".match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/);
console.log(match.groups.year); // "2026"A non-capturing group, (?:...), groups part of a pattern for alternation or a quantifier without capturing it.
How to use the regex tester
- Open the regex tester and type your pattern between the slashes, without delimiters.
- Turn flags on or off:
g(on by default),i,mands. - Paste your test text. Results update as you type, with every match highlighted in the text and a count of matches.
- If the pattern has groups, the Capture groups table lists each match with the text captured by group 1, group 2 and so on. Match details lists each full match with its index in the text.
The tester uses the JavaScript regex engine, so syntax specific to other engines, such as PCRE possessive quantifiers, may not work. Each run happens in a background worker and stops after five seconds, so a pattern with catastrophic backtracking (where the engine tries an exploding number of ways to match, as with (a+)+$ on a long string of a's) shows an error instead of freezing the page.
Practical examples
Patterns worth trying in the tester:
#[a-zA-Z0-9_]+\b(\w+)\s+\1\b<([a-z][a-z0-9]*)\b[^>]*>^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$One last tip: build a pattern a piece at a time and check the matches after each change. Writing the whole thing in one go and then debugging it is how regexes get their reputation.
