How this tester works
Patterns run with your browser’s own JavaScript regex engine, so what matches here matches in Node.js and front-end code. Each run happens in a background worker with a time limit. A pattern that backtracks catastrophically is stopped, and the page doesn’t freeze.
Flags
gfinds every match instead of stopping at the first.iignores case.mmakes^and$match at the start and end of each line, not only the whole text.slets.match newlines too.utreats the pattern as Unicode, so\u{1F600}and\p{L}(any letter) work.
Cheat sheet
. any character except newline
\d \w \s digit, word character [A-Za-z0-9_], whitespace
\D \W \S the opposite of each
[abc] one of a, b, c [^abc] anything except those
^ $ start / end \b word boundary
* + ? 0+, 1+, 0 or 1 {2,5} between 2 and 5
*? +? lazy: as few as possible
(x) capture group (?:x) group without capturing
(?<n>x) named group \1 back-reference to group 1
x(?=y) x followed by y x(?!y) x not followed by y
(?<=y)x x preceded by y (?<!y)x x not preceded by yReplacement patterns
In the replacement, $1 inserts the first capture group, $<name> a named group, $& the whole match and $$ a literal dollar sign. For example, pattern (\d{4})-(\d{2})-(\d{2}) with replacement $3/$2/$1 turns 2024-05-31 into 31/05/2024.
Catastrophic backtracking
Nested quantifiers like (a+)+$ or (\w+\s?)*$ can take exponential time on input that almost matches. On a server, this is a denial-of-service risk called ReDoS. Avoid quantifying a group that already contains a quantifier, and make alternatives mutually exclusive.
Differences from other languages
Java and Python use mostly the same syntax, with a few differences. Python writes named groups as (?P<name>…). Java strings need every backslash doubled ("\\d+"). Neither has a g flag: use Matcher.find() in a loop, or re.findall.