Originally published on zero2php.dev — part of the Zero to PHP course. View this lesson on the original site.

Manual: preg_match

The entry point for “does this string match?” is preg_match. Keep the official reference handy: preg_match (arguments, return values, and the optional $matches array).

PHP compiles PCRE patterns; related helpers include preg_match_all, preg_replace, and preg_quote when you need to treat user text as literal inside a pattern.

How hard to take this lesson right now

This is an introduction, not a “master regex today” requirement.

For this course, the important takeaway is:

  • regex exists for pattern-based text matching
  • preg_match() is the common entry point
  • you can come back later when you need richer patterns in real projects

If the patterns feel dense, that is normal. Learn the shape, complete the small exercise, and move on.

What preg_match does (in one breath)

  • preg_match(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0): int|false
  • Returns 1 if the pattern matches, 0 if not, or false on error.
  • With $matches, group 1 is the first capturing (...), 2 the next, and 0 the whole match—see the manual for details.

Example: currency amount

Extract digits after a $ sign:

<?php

declare(strict_types=1);

$s = 'Price: $12';

if (preg_match('/\$(\d+)/', $s, $m)) {
    echo "amount=", $m[1], "\n";
}

Example: UK-style postcode (illustrative)

UK postcodes follow predictable shapes (for example M1 1AA, SW1A 1AA), but real validation is fiddly—production code often uses a tested library or a maintained pattern. For learning, a simplified pattern can still show how preg_match pulls a substring out of a sentence:

<?php

declare(strict_types=1);

$address = 'Deliver to EC1A 1BB before noon';

// Simplified illustrative pattern—not a full postal authority ruleset.
if (preg_match('~\b([A-Z]{1,2}\d[A-Z0-9]?\s*\d[A-Z]{2})\b~i', $address, $m)) {
    echo $m[1], "\n";
}

Try changing the string to M1 1AA or W1K 6TN and confirm the captured group looks right.

Example: US ZIP code

Five digits, optional ZIP+4 after a hyphen:

<?php

declare(strict_types=1);

$label = 'Ship to 90210-1234';

if (preg_match('/\b(\d{5})(?:-(\d{4}))?\b/', $label, $m)) {
    echo 'ZIP5=', $m[1], ' ZIP4=', ($m[2] ?? ''), "\n";
}

Practical advice

Regex is powerful and easy to get wrong: test small cases, use preg_quote when mixing user literals into patterns, escape backslashes carefully in PHP strings, and prefer plain string functions when they are enough.

Revisit preg_match whenever you forget capture group order: https://www.php.net/manual/en/function.preg-match.php

Exercise

On $s = 'Price: $19', use preg_match (see the manual) to capture digits and echo the numeric part only (19).

From Zero to PHP — Control flow, functions, arrays, and the web