How to use it
- Put the pattern on the first line.
/pattern/flagsis accepted, or just the bare pattern. - Add a line containing only
<<<, then the text to test against. - Read the match list, the highlighted text, and the pattern breakdown.
What the three panes tell you
The match list is the ground truth: each match with its offset, plus every numbered and named capture group. This is where you catch the classic off-by-one — a group that captured an empty string instead of nothing, or matched one character more than intended.
The highlighted view shows the matches in context. It answers a different question: not "what did it capture" but "did it find them all". A pattern that works on your example and silently skips the third line is obvious here and invisible in a match count.
The explanation decomposes the pattern token by token. It is most useful on someone else's regex — the ones that arrive in a code review with no comment.
Two mistakes that account for most confusion
Escaping. A regex written inside a string literal is escaped twice. In C# "\\d+" is the pattern \d+; in a verbatim string @"\d+" it is the same thing written once. When a pattern that works in a tester fails in code — or the reverse — count the backslashes first.
Greediness. Quantifiers are greedy by default: they consume as much as they can, then give characters back only as needed to let the rest of the pattern match. ".*" against "a" and "b" matches the entire string including the middle, because the final " can be satisfied by the last quote. Add ? to make it lazy — ".*?" — and you get the two intended matches. Most "my regex grabbed too much" bugs are this.
Catastrophic backtracking is a security issue
Some patterns take exponential time on inputs that nearly match. The textbook case is (a+)+$ fed a long string of a followed by b: the engine tries every way of splitting the as before concluding there is no match.
This matters because regular expressions frequently validate user input. A pattern with nested quantifiers over overlapping alternatives — email validators are a common offender — becomes a denial-of-service vector: one crafted request pins a CPU core. It has a name, ReDoS, and it appears in real incident reports.
Three defences. Avoid nesting quantifiers over patterns that can match the same text in multiple ways. Test with near-miss inputs, not just matching ones, since the pathological case is always a failure to match. And in .NET, pass a matchTimeout to Regex — a hard ceiling costs nothing and turns a hang into an exception you can handle.
Where JavaScript and .NET differ
The syntax overlaps heavily, so a pattern tested here will usually behave the same in C#. The gaps worth knowing:
- Balancing groups — .NET's
(?<open>)/(?<-open>)can match nested structures. JavaScript has nothing comparable. - Lookbehind — long a .NET feature, now standard in JavaScript too, but check your target runtime.
RegexOptions.IgnoreCaseand culture — .NET case-insensitivity is culture-sensitive by default, which produces the Turkishiproblem: under a Turkish culture,Iandiare not a case-insensitive match. UseCultureInvariantunless you specifically want locale rules.- Named group access — .NET exposes
match.Groups["name"]; JavaScript usesmatch.groups.name.