Write a pattern. Watch it match, token by token.
Test JavaScript regular expressions against your own text. Matches light up as you type, capture groups are listed, and every part of the pattern is explained in plain English underneath.
Each loads into the tester with sample text that includes a few near-misses, so you can see what it accepts and what it rejects. The note says where each one is too strict or too loose.
/[\w.+-]+@[\w-]+\.[\w.-]+/giPractical, not RFC-perfect: accepts most real addresses, rejects obvious junk./\b[A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}\b/giChecks the shape, not whether the postcode exists./\b(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])\b/gGroups capture year, month and day. Still allows 30 February./https?:\/\/[\w.-]+(?:\.[a-z]{2,})(?:\/[^\s]*)?/giNeeds http(s)://. Add (?:https?:\/\/)? to accept bare www. addresses./#(?:[0-9a-f]{3}){1,2}\b/giMatches 3- and 6-digit colours. It doesn’t accept the 4- or 8-digit forms that include transparency./(?:\+44\s?7|07)\d{3}\s?\d{6}/gAllows one optional space after the prefix; landlines are rejected./#[A-Za-z]\w{1,29}/gMust start with a letter; stops at 30 characters./£\d{1,3}(?:,\d{3})*(?:\.\d{2})?/gAccepts thousands separators and optional pence.The most common regex surprise: .+ runs to the last possible match, swallowing everything in between. Switch between the three versions to see what each captures from the same line.
Click any token to add it to the end of your pattern in the tester.
\da digit\wword character\swhitespace.any character[a-z]one of a range+one or more*zero or more?optional{3}exactly 3{2,5}2 to 5^start$end\bword edge(?=x)followed by x(?!x)not followed by x( )capture(?: )group only(?<n> )named groupa|ba or b\1repeat group 1JavaScript, PCRE, Python and Java use backtracking engines. When a nested quantifier like (a+)+ fails to match, the engine tries every way of splitting the input between the inner and outer loop: 2ⁿ ways for n characters. This is the root of ReDoS outages. Press Run to time it in your browser on strings of growing length.
/^(a+)+$/exponentialNested quantifiers: the textbook ReDoS pattern./^(a|aa)+$/exponentialOverlapping alternatives: two ways to consume each pair of a’s./^(a|a?)+$/exponentialAn optional branch that overlaps the other branch./^a+$/linearThe same language as the first pattern, written without nesting.play_arrowRun /^(a+)+$/There’s no single regex language. Go’s RE2 drops backreferences and lookaround to guarantee linear time; POSIX tools lack lazy quantifiers; JavaScript only gained lookbehind in 2018. The JavaScript column is tested live by compiling each example in this browser. Click a row to load it into the tester.
/a+?/check_circlecheck_circlecheck_circlecheck_circlecancelcheck_circle/q(?=u)/check_circlecheck_circlecheck_circlecancelcancelcheck_circle/(?<=\$)\d+/check_circlechange_circlechange_circlecancelcancelcheck_circle/(?<year>\d{4})/check_circlecheck_circlechange_circlecheck_circlecancelcheck_circle/(\w)\1/check_circlecheck_circlecheck_circlecancelchange_circlecheck_circle/\p{L}+/ucheck_circlecheck_circlecancelcheck_circlecancelcheck_circle/(?>a+)b/check_circlecheck_circlecheck_circlecancelcancelcancel/a++b/check_circlecheck_circlecheck_circlecancelcancelcancel/(?i:abc)/check_circlecheck_circlecheck_circlecheck_circlecancelcheck_circle/[\p{L}--[a-z]]/vcancelcancelcancelcancelcancelchange_circle/a(?R)?b/check_circlecancelcancelcancelcancelcancelAll eight flags defined by ECMAScript, each checked against this browser, plus the dates regular expressions changed, from Kleene’s notation to the v flag.
Developer tools people use alongside this one.