Write a pattern, see every match highlighted live, and inspect each capture group — nothing you type ever leaves your browser.
The most common tokens, in case you need a refresher.
. any character except line break\d digit — \D non-digit\w word char — \W non-word\s whitespace — \S non-whitespace[abc] any of a, b, c[^abc] none of a, b, c[a-z] range a to z^ start of string / line$ end of string / line\b word boundary — \B not* 0 or more — + 1 or more? 0 or 1{n} exactly n{n,} n or more{n,m} between n and m*? lazy (fewest possible)(...) capturing group(?:...) non-capturing group(?<name>...) named groupa|b a or b(?=...) lookahead(?!...) negative lookahead