Regex is most useful when it is treated as a small, testable language rather than a mysterious line of punctuation. This regex cheat sheet explains the core patterns, shows practical examples, and provides a repeatable workflow for building, testing, documenting, and maintaining regular expressions in real applications.
Overview
A regular expression describes text by combining literal characters with rules such as character classes, repetition, boundaries, groups, and alternatives. The same idea appears in JavaScript, Python, PHP, Java, .NET, Ruby, command-line tools, database clients, and many developer tools. However, syntax and supported features vary between regex flavors, so a pattern that works in one environment may need adjustment in another.
The safest approach is to begin with the smallest pattern that expresses the requirement, test it against both expected and unexpected input, and then place it in the actual application environment. A regex tester is useful during exploration, but it does not replace tests in your programming language or framework.
Core regex syntax
| Pattern | Meaning | Example |
|---|---|---|
. | Any character except a line terminator in many flavors | a.c matches abc and a-c |
\d | A digit in many flavors | \d{4} matches four digits |
\w | A word character, often a letter, digit, or underscore | \w+ matches a word-like sequence |
\s | Whitespace | \s+ matches one or more spaces or line breaks |
[abc] | One character from the set | [aeiou] matches one vowel |
[^abc] | One character not in the set | [^,]+ matches non-comma characters |
^ | Start of a string or line, depending on mode | ^GET |
$ | End of a string or line, depending on mode | done$ |
* | Zero or more repetitions | ab* matches a and abbb |
+ | One or more repetitions | ab+ matches ab and abbb |
? | Optional or lazy, depending on position | colou?r |
{m,n} | Between m and n repetitions | \d{2,4} |
| | Alternation | cat|dog |
(...) | Capturing group | (\d{4})-(\d{2}) |
(?:...) | Non-capturing group where supported | (?:https?://) |
Escape a metacharacter when you need its literal meaning. For example, \. matches a period, \? matches a question mark, and \+ matches a plus sign. Remember that programming-language string literals may require a second layer of escaping. A pattern written as \d+ in a regex tester may appear as \\d+ in a language string, depending on the language.
Step-by-step workflow
1. Define the input and the desired result
Write down what should match, what should not match, and what you want to extract or replace. “Validate an email” is too broad to guide a reliable pattern. “Accept a required local part and domain in a form field, then let the mail system handle deeper validation” is a more useful boundary.
Also decide whether you are searching within larger text or validating the entire value. Searching for a date inside a paragraph usually does not need string anchors. Validating a form field generally does.
2. Start with literals and character classes
Build the expression from recognizable pieces. For a simple product code made of two uppercase letters, a hyphen, and four digits, begin with [A-Z]{2}-\d{4}. If the complete input must contain only that code, add anchors: ^[A-Z]{2}-\d{4}$, subject to the newline behavior of your chosen flavor.
Prefer explicit classes when the allowed characters matter. \w is convenient, but its exact character set can differ by engine and flags. A class such as [A-Za-z0-9_] communicates a narrower rule more clearly when that is what the application requires.
3. Add groups for structure and extraction
Groups let you apply repetition to several tokens or capture useful parts. The pattern (\d{4})-(\d{2})-(\d{2}) separates a date into year, month, and day captures. If a group is needed only for precedence, use a non-capturing group such as (?:jpg|png|gif) where the flavor supports it. Unnecessary captures make replacement logic and match results harder to read.
4. Use boundaries deliberately
Word boundaries, written as \b in many engines, can prevent a search for cat from matching the middle of education. They are not universal “word” definitions, however; behavior depends on the engine and character set. For structured text, explicit separators or lookarounds may be clearer.
5. Add lookarounds only when they improve the rule
A positive lookahead checks what follows without consuming it: \d+(?= USD) finds digits immediately followed by a space and USD. A negative lookahead rejects a following condition: ^(?!admin$)[A-Za-z0-9_]+$ allows a username format while excluding the exact value admin.
Lookbehind, such as (?<=\$)\d+, checks text before the match, but support varies more than for basic syntax. Confirm compatibility before using it in shared or cross-platform code. When a lookaround makes a pattern difficult to explain, a two-step parse may be the more maintainable solution.
6. Test with a deliberate case matrix
Do not test only the example that inspired the regex. Include a normal valid value, the shortest valid value, a value just outside each limit, empty input, whitespace, unexpected punctuation, mixed case, accented or non-ASCII text when relevant, line breaks, and unusually long input. For a date pattern, test impossible dates too: a regex can verify shape without proving that a calendar date exists.
7. Move the tested pattern into code
Copy the expression into a unit or integration test using the same flags, input encoding, and API used by the application. Test capture groups and replacement output as well as whether a match exists. Add regression cases whenever a bug reveals an input the original test set missed.
Tools and handoffs
A regex tester is a practical place to compare a pattern with sample text, inspect groups, switch flags, and identify where matching stops. Use a tool that lets you select the target flavor, because features such as named groups, Unicode classes, lookbehind, and newline handling are not identical everywhere.
Keep a small handoff record with four items:
- Purpose: what the expression finds, validates, extracts, or replaces.
- Flavor: the language, runtime, or tool in which it is expected to run.
- Flags: such as case-insensitive, multiline, global, dot-all, or Unicode mode.
- Examples: positive cases, negative cases, and expected captures or replacements.
For replacement tasks, document the replacement string separately. A regex may correctly capture a year and month while the replacement syntax still differs between JavaScript, Python, and other languages. If the pattern is used in a parser, log processor, or request filter, review its behavior with representative production-shaped data without exposing sensitive values.
Regex can be one step in a broader developer-tool workflow. A JSON formatter may make structured samples readable before you extract fields; a URL encoder can clarify whether punctuation is data or syntax; and a debugging workflow can help separate a matching problem from an upstream data problem. These tools complement the expression, but none should hide the input assumptions behind it. For a wider reference, see the developer cheatsheet for JSON, Regex, SQL, URLs, and Base64.
Quality checks
Check anchors and mode flags
Ask whether the pattern should match one complete value or a line within a larger document. Multiline mode can change how ^ and $ behave. Global mode can change how an API advances through matches. Dot-all mode can change whether . crosses line breaks. These are behavioral choices, not cosmetic switches.
Check greediness and scope
Quantifiers are greedy by default in many flavors. A pattern such as <.*> can consume from the first opening angle bracket to the last closing angle bracket in a line. A lazy form such as <.*?> may stop earlier, but neither approach is a substitute for a proper HTML parser when the input is HTML. Limit character classes where possible, for example <[^>]*> for a narrow tag-shaped task.
Check performance and failure behavior
Nested ambiguous quantifiers and broad alternatives can cause excessive backtracking in some engines. Keep patterns specific, avoid repeating large groups unnecessarily, and test long non-matching inputs. If a pattern processes untrusted text, include performance review in the same way you review memory and query behavior.
Check readability
Use named groups where supported and useful, split complicated expressions into smaller stages, or add a verbose mode with comments when the flavor allows it. A short regex is not automatically a clear regex. The next developer should be able to identify the accepted format and the intentional exclusions without reverse-engineering every symbol.
When to revisit
Revisit a regex when the input contract changes, a new locale or character set is supported, the application switches languages or runtimes, a regex library changes behavior, or users produce valid cases that were not in the original test matrix. Also review patterns after changing flags, capture-group numbering, replacement logic, or the surrounding parser.
Make the update practical: keep the original requirement visible, add a failing test for the new case, change the smallest part of the pattern that solves it, and run the complete case matrix. Then update the comment or documentation with the new examples and target flavor. If the expression has become a dense collection of exceptions, pause and ask whether a parser, structured validation library, or several simpler checks would better express the rule.
For future work, save this compact routine beside the pattern: define the boundary, identify the flavor, build from simple tokens, test positive and negative cases, verify captures and replacements in code, check performance, and document the assumptions. That workflow turns a regex cheat sheet from a list of symbols into a maintainable reference.