Wernzi Tools

Wernzi Tools Guide

Regular Expressions for Beginners

Regular expressions let you search, validate and transform text with patterns. A gentle introduction with practical examples for email, dates and more.

By Wernzi Tools team · Published November 6, 2026 · 7 min read · Updated November 2026

A regular expression — regex for short — is a tiny pattern language for describing text. With a few characters you can say "find every email address in this document", "check that this password contains a number", or "replace all dates with a new format". Once learned, regex saves hours of manual text wrangling.

Regex has a reputation for looking like keyboard noise, but it is built from a small set of simple ideas. This guide introduces them one at a time, with examples you can try in a regex tester as you read.

Matching literal text and wildcards

The simplest regex is plain text: the pattern "cat" matches the letters c-a-t wherever they appear. The dot is your first special character — it matches any single character, so "c.t" matches "cat", "cut" and "c3t". Square brackets define a set: "[aeiou]" matches any single vowel, and "[0-9]" matches any digit. A caret inside brackets negates the set, so "[^0-9]" matches any character that is not a digit.

These three pieces — literals, dots and character classes — already cover a surprising number of real searches. Need to find a three-letter word starting with "b"? The pattern "b.." does it. Need any hex digit? "[0-9a-fA-F]" is the classic answer.

cat      -> matches "cat" in "concatenate"
c.t      -> matches "cat", "cut", "c3t"
[0-9]    -> matches any single digit
[^0-9]   -> matches any non-digit

Quantifiers: how many?

Quantifiers say how many times the previous element may repeat. The asterisk (*) means zero or more, the plus (+) means one or more, and the question mark (?) means zero or one. Curly braces give exact control: "a{3}" matches exactly three a's, "a{2,4}" matches two to four, and "a{2,}" matches two or more.

Quantifiers are greedy by default: they match as much as they can. That matters when you parse text with repeated structure — the pattern "<.+>" applied to "<b>bold</b>" matches the whole string, not just "<b>". Adding a question mark after the quantifier ("<.+?>") makes it lazy, matching as little as possible. This greedy-versus-lazy distinction is the single most common source of regex surprises.

Anchors and boundaries

Anchors pin a match to a position instead of a character. The caret (^) matches the start of the text (or line), and the dollar sign ($) matches the end. So "^hello" only matches "hello" at the very beginning, and "^[0-9]+

quot; matches a string that consists entirely of digits — a classic whole-input validation pattern.

The word boundary \b is subtler and extremely useful: it matches the invisible edge between a word character and a non-word character. The pattern "\bcat\b" finds the word "cat" but not "concatenate" or "cats". Use it whenever you want whole words instead of substrings.

Groups and alternation

Parentheses group parts of a pattern together, so a quantifier can apply to several characters at once: "(ab)+" matches "ab", "abab" and so on. Parentheses also capture — the matched text is remembered and can be reused in a replacement, which is how find-and-replace tools reformat dates or swap name order.

The pipe (|) means "or": "cat|dog" matches either word. Combined with groups, alternation handles real-world variation: "(Mr|Mrs|Ms)\. [A-Z][a-z]+" matches a formal name with any of the three titles. Keep groups small and purposeful; deep nesting is where regex becomes unreadable.

Practical patterns to start with

The best way to learn regex is to use it on small, real problems. Validating an email address is the classic exercise — a simple version is "^[^\s@]+@[^\s@]+\.[^\s@]+

quot;, which checks for something, an @, something, a dot and something. It is not a perfect email validator (no regex truly is), but it catches the common typos. Extracting dates, cleaning up whitespace with "\s+", and validating phone numbers are all one-liners once the building blocks click.

Two habits will save you pain. First, always test your pattern against both text it should match and text it should not — a pattern that matches everything is as useless as one that matches nothing. Second, keep patterns short and comment anything clever; a regex you cannot read next month is a bug waiting to happen. Paste your test cases into a regex tester and iterate there instead of guessing in production code.

  • Email (simple check): ^[^\s@]+@[^\s@]+\.[^\s@]+$
  • Only digits: ^[0-9]+$
  • Date YYYY-MM-DD: ^\d{4}-\d{2}-\d{2}$
  • Collapse whitespace: \s+ → single space

Building a pattern step by step: a username validator

Let us build a real pattern from scratch: a username that is 3 to 16 characters long and may contain letters, digits and underscores. Start with the character class [a-zA-Z0-9_]. Then add the length with a quantifier: {3,16}. That gives [a-zA-Z0-9_]{3,16}. Finally, anchor it so the whole input must match: ^[a-zA-Z0-9_]{3,16}$. Each piece is simple; the power comes from combining them.

Test it against good and bad inputs: "ada_42" should match, "a" should fail (too short), "ada-lovelace" should fail (the hyphen is not allowed), and "ada lovelace" should fail (the space is not allowed). When a test fails unexpectedly, remove the anchors and test the pieces one at a time — most regex bugs are a single character in the wrong place.

Regex flavors: why the same pattern behaves differently

Regex is not one language: JavaScript, Python, Java, Go and PCRE each have their own flavor, with different features and escaping rules. A pattern that works in Python may fail in JavaScript — lookbehinds, named groups and Unicode classes are common differences. Always test your pattern in the language you will run it in, and keep a regex tester set to that flavor while you develop.

Try it yourself

Put what you just read into practice with these free tools — no sign-up needed.

Keep learning

Browse all guides →