Regular Expressions

A regular expression — "regex" — is a tiny pattern language for describing text. With a handful of symbols you can validate an email, pull every number out of a log line, or clean up messy input. It looks cryptic at first, but the core vocabulary is small, and once it clicks you'll reach for it constantly. This lesson builds that vocabulary from the ground up using C#'s Regex class.

Learn Regular Expressions in our free C# course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick recall.

Part of the free C# course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

A regex is like a search filter on steroids . A normal "find" box looks for exact text — "find cat ". A regex lets you describe a shape instead: "find any 5-digit number", "find any word starting with a capital letter", "find anything that looks like an email". You're not searching for a specific string, you're searching for a kind of string — and that's enormously powerful.

1. Does It Match? Regex.IsMatch

The simplest question is a yes/no: does the text contain something matching the pattern? Regex.IsMatch answers it. Patterns are built from metacharacters like \d (a digit) and quantifiers like + (one or more). Wrap a pattern in ^...$ to require the whole string to match — the key trick for validation.

2. The Core Metacharacters

The whole language is built from a small set of pieces: character classes ( \d , \w , \s ), the wildcard . , quantifiers ( + , * , ? , {' '} ), character sets ( [abc] ), and alternation ( x|y ). Combine them and you can describe surprisingly specific patterns.

3. Finding Matches: Match & Matches

IsMatch only says yes/no. To actually get the matched text, use Regex.Match for the first hit (with .Value and .Index ) or Regex.Matches to iterate over every match. Extracting all the numbers from a string is a classic one-liner.

Your turn — write an email check and extract all the words from a sentence.

4. Groups & Replacement

Parentheses (...) capture parts of a match into groups . Named groups (?<year>\d{' '}) are the clearest way to pull structured data out of text. And Regex.Replace can rewrite text using those groups via $1 , $2 — perfect for reformatting.

These lines validate a 4-digit PIN, but they're scrambled. Order them so the program compiles and prints whether the PIN is valid.

The input and the pattern must both exist before IsMatch uses them; the result ok must exist before it's printed.

True — the string contains digits (123), so \d+ finds a match.

False — the anchors require the WHOLE string to be digits, but it starts with letters.

a*b*c* — every digit is replaced by an asterisk.

Cleaning and validating user input is regex's daily bread. Here it strips non-digits from a phone number, validates a username, and collapses messy whitespace.

Pull every hashtag out of a social-media post. A clean, real use of Regex.Matches with a simple pattern.

Practice quiz

What does the metacharacter \d match?

  • Any whitespace character
  • Any word character
  • A single digit 0-9
  • The end of a line

Answer: A single digit 0-9. \d matches a single digit; \w is a word char and \s is whitespace.

What does the quantifier + mean in a regex?

  • One or more
  • Zero or one
  • Zero or more
  • Exactly one

Answer: One or more. + means one or more; * means zero or more, and ? means zero or one.

What do the anchors ^ and $ do?

  • Match any character
  • Escape special characters
  • Create a capture group
  • Anchor to the start and end of the string

Answer: Anchor to the start and end of the string. ^ anchors to the start and $ to the end, so ^...$ requires the whole string to match.

Which Regex method returns a simple bool 'is there a match anywhere?'

  • Regex.Match
  • Regex.IsMatch
  • Regex.Matches
  • Regex.Replace

Answer: Regex.IsMatch. IsMatch returns a bool; Match returns the first match's details and Matches returns all matches.

What does the quantifier ? mean (as in colou?r)?

  • The preceding item is optional (zero or one)
  • One or more of the preceding
  • Any single character
  • Start of a group

Answer: The preceding item is optional (zero or one). ? makes the preceding item optional - zero or one occurrence - so colou?r matches both color and colour.

In Regex.Replace, how do you refer to the first captured group in the replacement string?

  • \1
  • {1}
  • $1
  • %1

Answer: $1. Numbered groups are referenced as $1, $2, etc. in the replacement string.

How do you read a named group from a match, e.g. (?<year>\d{4})?

Named groups are read with m.Groups["year"].Value.

Why are verbatim strings @"..." recommended for regex patterns?

  • They run faster
  • They enable named groups
  • They anchor the pattern automatically
  • Backslashes stay literal, so \d doesn't need doubling

Answer: Backslashes stay literal, so \d doesn't need doubling. In a verbatim string backslashes are literal, so @"\d+" stays readable instead of "\\d+".

What does \D match?

  • A digit
  • Any character that is NOT a digit
  • A word boundary
  • A literal D

Answer: Any character that is NOT a digit. Uppercase \D is the negation - it matches any non-digit character.

Why does \d+ match the string "abc123" while ^\d+$ does not?

  • \d+ is case-insensitive
  • \d+ matches letters too
  • ^\d+$ requires the WHOLE string to be digits; \d+ only needs some digits somewhere
  • They behave identically

Answer: ^\d+$ requires the WHOLE string to be digits; \d+ only needs some digits somewhere. Without anchors \d+ matches any digits within the string; ^\d+$ requires the entire string to be digits.