PHP Regex Tutorial: PHP preg_match
Overview
- Regular expressions let you search, validate, and extract parts of strings with compact patterns. In PHP, regex features come from PCRE (Perl Compatible Regular Expressions) and are exposed through the
preg_*
functions. - If you are new to this topic, think of a Regex pattern as a tiny language for describing, parsing, and matching text. You match against input, check if it fits, and pull out the pieces you care about.
- This quick Regex tutorial, with a PHP spin, focuses on
preg_match
and the essentials you need to use it well.
Problem
- You need to test whether a string matches a pattern and optionally extract captured parts.
- You want a simple, correct example of using
preg_match
with delimiters, modifiers, and groups.
Solutions
- Use
preg_match
to test for a match and read captured groups. - Use
preg_match_all
if you need every occurrence, not just the first. - Prefer clear delimiters and readable modifiers.
<?php
$input = 'Order #A-12345 placed by Ada on 2025-08-30';
$pattern = '/^Order\s+#([A-Z]-\d+)\s+placed\s+by\s+([A-Za-z]+)\s+on\s+(\d{4}-\d{2}-\d{2})$/';
if (preg_match($pattern, $input, $m)) {
// $m[0] is the full match; $m[1..] are captured groups.
[$full, $orderId, $customer, $date] = $m;
echo "$orderId for $customer on $date\n";
} else {
echo "No match\n";
}
<?php
// Named capture groups and modifiers (case-insensitive + unicode):
$pattern = '/^(?P<user>[[:alpha:]\p{L}]+)\s*<(?P<email>[^>]+)>$/iu';
if (preg_match($pattern, 'Ada <ada@example.com>', $m)) {
echo $m['user'] . ' -> ' . $m['email'] . PHP_EOL;
}
Check out the official docs for further details on how to use preg_match properly in your PHP page.
PHP preg_match
Use PHP’s preg_match()
to test if a pattern occurs and to capture groups from the first match:
<?php
$hasDigits = preg_match('/\d+/', 'file_007.txt') === 1; // true
PHP Regular Expression Basics
A PHP regular expression uses delimiters (often /.../
) and optional modifiers like i
(case-insensitive), m
(multiline), s
(dot matches newline), and u
(UTF-8).
<?php
// Delimiters can be '/', '#', or other non-alphanumeric chars:
$pattern = '#^https?://([a-z0-9.-]+)/?$#i';
if (preg_match($pattern, 'https://learnprogramming.us/', $m)) {
echo "Host: {$m[1]}\n";
}
Regex Tutorial PHP — Quick Start
This gives a compact regex tutorial php: use anchors ^
and $
to match the whole string, groups (...)
to capture, and quantifiers like +
, *
, and {m,n}
to control repetition.
<?php
$pattern = '/^([A-Z]{2})-(\d{4,6})$/';
preg_match($pattern, 'AB-123456', $m);
[$full, $prefix, $num] = $m;
Other PHP String Matching Options
You can go beyond preg_match
when it fits the problem better.
<?php
// All matches:
preg_match_all('/\b\w+\b/u', 'one two three', $m);
// Replace:
echo preg_replace('/\s+/', ' ', "a b c");
// Non-regex alternatives (faster for simple cases):
var_dump(str_contains('hello world', 'world')); // PHP 8+
var_dump(str_starts_with('hello', 'he')); // PHP 8+
Things to Consider
- Use readable delimiters and comment your patterns when they grow complex.
- Validate inputs defensively; catastrophic backtracking can hurt performance on hostile strings.
- Prefer non-regex string functions for trivial checks; they are faster and clearer.
- Check out our Regex 101 Tutorial article for a deeper guide and a handy Regex cheat sheet.
Match with Regex and NOT Something Else
If you are trying to search for something with Regex, and not for something else, then it means you’re looking for a “negative lookahead” or “negative lookbehind”, in Regex terminology.
A Negative Lookahead is a Regex feature that allows you to assert that a certain pattern does not follow the current position in the string (Denoted by (?!...)
), and you can use the preg_match()
function, along with the negative lookahead, to accomplish this.
Here’s a simple example:
$pattern = '/^((?!not).)*$/'; // Matches any string that does not contain 'not'
$string = "This is a test string.";
if (preg_match($pattern, $string)) {
echo "Match found!";
} else {
echo "No match.";
}
- Pattern Breakdown:
^
: Asserts the start of the string.((?!not).)*
: This part matches any character (.
) zero or more times (*
), but only if it is not followed by the string “not”.$
: Asserts the end of the string.
By using negative lookahead in PHP, with preg_match()
, you can effectively filter out unwanted patterns while still matching the desired criteria.
Gotchas
- Patterns must be wrapped in delimiters (typically using forward slashed (
/
)/like-this/
). - Always escape the delimiter inside the pattern or choose a different delimiter.
preg_match
returns1
for a match,0
for no match, andfalse
on error—do not treat it as boolean blindly.- Use
u
for UTF-8 if you expect non-ASCII letters. - Avoid unbounded
.*
with greediness when you mean “a little”; prefer precise classes and?
.
Sources
Further Investigation
- Read the PCRE pattern syntax reference in the PHP manual for advanced constructs.
- Explore an online php regex generator or tester to iterate on patterns safely.
- Learn grouping, lookarounds, and backreferences with a focused php regex tutorial and then port patterns to your codebase.
TL;DR
- Use
preg_match('/pattern/', $str, $m)
to test and capture; usepreg_match_all
for all matches; choose clear delimiters and addu
for UTF-8 when needed.
<?php
if (preg_match('/^([A-Z]{2})-(\d{4})$/u', 'AB-1234', $m)) {
echo "{$m[1]} / {$m[2]}\n";
} else {
echo "No match\n";
}
We also have a Python re regular expression blog post for more ways you can use RegEx to parse, match, and replace characters in strings.