UtilityBase logoUtilityBase

2 min read

Regex Basics for Beginners

A plain-English tour of the metacharacters, character classes, quantifiers, and anchors that make up most patterns — plus the greedy-matching trap.

Literals and metacharacters

A regular expression is a pattern that describes text. Most characters are literals — the pattern cat matches the letters c, a, t in order. The power comes from metacharacters, which have special meaning. The dot . matches any single character; \d matches any digit; \w matches a word character (letters, digits, underscore); \s matches whitespace. So \d\d:\d\d matches a time like 09:45, and c.t matches cat, cot, or cut.

Because metacharacters are special, matching one literally means escaping it with a backslash: to match an actual dot (like in a file name) you write \. — the pattern file\.txt matches 'file.txt' but not 'fileXtxt'. Forgetting to escape is the most common beginner bug, since . silently matches far more than intended.

Classes, quantifiers, and anchors

Character classes in square brackets match any one of a set: [aeiou] matches a single vowel, [a-z] any lowercase letter, [0-9] any digit, and a leading caret negates it — [^0-9] matches any non-digit. Quantifiers say how many times: * is zero or more, + is one or more, ? is zero or one, and {2,4} is between two and four. So [a-z]+ matches a run of lowercase letters and \d{3}-\d{4} matches 555-1234.

Anchors pin a pattern to a position rather than matching characters. ^ means start of the string (or line), $ means end. ^\d+$ means 'the entire string is nothing but digits' — useful for validation, because without anchors \d+ would happily match the '5' inside 'abc5def'. The word boundary \b matches the edge between a word and a non-word character, so \bcat\b matches 'cat' but not 'category'.

  1. 1Open the Regex Tester and paste some sample text to match against.
  2. 2Start with a literal, then swap in classes: change cat to c[aou]t and watch what matches.
  3. 3Add a quantifier like \d{3,} and see how the match grows.
  4. 4Anchor it with ^…$ to require the whole string to match, not just part.
  5. 5Toggle flags (like case-insensitive and global) and watch the highlighted matches update.

Groups and the greedy trap

Parentheses create groups, which let a quantifier apply to a whole chunk and let you capture part of a match for reuse. (ab)+ matches 'ababab'; in a find-and-replace, capture groups become $1, $2 so you can reorder or extract pieces. The pipe | means 'or' inside a group: (cat|dog) matches either word. Groups are where regex stops being validation and becomes a text-transformation tool.

The classic gotcha is greedy matching. By default * and + grab as much as possible, so the pattern <.+> against '<a> <b>' matches the entire '<a> <b>' rather than just '<a>' — because .+ swallows everything up to the last >. Add a ? to make a quantifier lazy (.+?) and it takes as little as possible, matching '<a>' then '<b>' separately. Greedy-by-default surprises nearly everyone once, and the lazy ? is the fix.

Frequently asked questions

What's the difference between * and +?

Both are quantifiers, but * matches zero or more of the preceding item (so it can match nothing), while + requires one or more (at least one). Use + when the thing must appear at least once, and * when it's optional or repeatable including absent.

Why does my pattern match too much?

Almost always greedy matching: * and + grab as much as they can. A pattern like .+ between delimiters swallows everything up to the last one. Make the quantifier lazy by adding a ? (.+?) so it takes as little as needed and stops at the first match.

How do I match a literal special character like a dot?

Escape it with a backslash. The dot . normally matches any character, so to match an actual period you write \.. The same applies to other metacharacters — \*, \+, \?, \( — when you want the literal symbol rather than its special meaning.

Tools mentioned in this guide

Keep reading