SomeeLab.tools

Regex Tester

Test a regular expression against your own text and see every match highlighted, with capture groups and a live replace preview.

What the four flags do

g off means only the first match is found. Turn it on to count occurrences or replace them all.

i ignores case. m makes ^ and $ bind to each line rather than to the whole string, which is what you want when picking line starts out of a log.

s lets . match a newline. By default the dot skips line breaks, so a block spanning several lines needs this flag to be captured whole.

Pieces worth memorising

  • \d digits, \w letters, digits and underscore, \s whitespace. Capitalised (\D \W \S) they mean the opposite.
  • + one or more, * zero or more, ? optional, {2,4} between two and four.
  • ^ start, $ end, \b word boundary.
  • (...) captures into the result; (?:...) groups without capturing.
  • (?<name>...) gives a group a name so you can read it back by name instead of number.

Greedy versus lazy

.* runs as far as it can and then backs off. Applied to <b>one</b><b>two</b>, the pattern <b>.*</b> swallows the lot as a single match.

Adding ? to make <b>.*?</b> stops at the earliest opportunity, giving two matches instead. For anything inside tags or quotes, lazy is usually the one you want.

Why this runs on a separate thread

Nested quantifiers can make an expression explode. Give (a+)+b a string of thirty a characters and the engine tries every way of splitting them, so the work grows by orders of magnitude. A tiny input can occupy it for minutes.

This tool evaluates the pattern on a thread of its own and kills that thread outright after one second. There is no way to interrupt it partway, because the whole thing happens inside a single call. That is why a runaway pattern here leaves the page responsive.

The same behaviour on a server ties up a request. If user input reaches a regular expression in your code, nested quantifiers are the thing to look for.

Syntax differs between languages

What runs here is JavaScript’s flavour. Lookbehind ((?<=...)) works in current browsers, but PCRE-only features such as recursion and atomic groups do not exist.

Python writes named groups as (?P<name>...), and Java needs the backslashes escaped again inside a string literal. Translate the notation when you move a pattern you worked out here.