PHP Regular Expressions
A regular expression (regex) is a pattern used to match, search, and manipulate strings. Regular expressions are powerful tools for validating email addresses, phone numbers, and postal codes; searching text for patterns; extracting specific parts of strings; and replacing text based on patterns. PHP uses PCRE (Perl Compatible Regular Expressions) through functions prefixed with preg_.
Regular Expression Syntax
A regex pattern in PHP is written as a string enclosed in delimiters — typically forward slashes: /pattern/flags.
| Element | Meaning | Example |
|---|---|---|
. | Any single character except newline | /c.t/ matches "cat", "cut", "cot" |
* | 0 or more of previous | /go*/ matches "g", "go", "goo" |
+ | 1 or more of previous | /go+/ matches "go", "goo" but not "g" |
? | 0 or 1 of previous (optional) | /colou?r/ matches "color" and "colour" |
{n} | Exactly n times | /\d{4}/ matches exactly 4 digits |
{n,m} | Between n and m times | /\d{2,4}/ matches 2 to 4 digits |
^ | Start of string | /^Hello/ matches strings beginning with "Hello" |
$ | End of string | /world$/ matches strings ending with "world" |
[abc] | One of these characters | /[aeiou]/ matches any vowel |
[^abc] | Not one of these characters | /[^0-9]/ matches any non-digit |
(abc) | Capture group | /(hello)/ captures "hello" |
a|b | a or b | /cat|dog/ matches "cat" or "dog" |
\d | Any digit (0-9) | /\d+/ matches one or more digits |
\w | Word character (letters, digits, underscore) | /\w+/ matches a word |
\s | Whitespace (space, tab, newline) | /\s+/ matches whitespace |
preg_match() — Test if a Pattern Matches
Returns 1 if the pattern is found, 0 if not. An optional third argument captures matched groups.
<?php
$email = "user@example.com";
if (preg_match("/^[\w.-]+@[\w.-]+\.[a-z]{2,}$/i", $email)) {
echo "Valid email address.";
} else {
echo "Invalid email address.";
}
?>
Using Capture Groups
<?php
$dateString = "Today is 2026-03-17.";
if (preg_match("/(\d{4})-(\d{2})-(\d{2})/", $dateString, $matches)) {
echo "Full match: " . $matches[0]; // 2026-03-17
echo "Year: " . $matches[1]; // 2026
echo "Month: " . $matches[2]; // 03
echo "Day: " . $matches[3]; // 17
}
?>
preg_match_all() — Find All Matches
<?php
$html = '<a href="https://google.com">Google</a> and <a href="https://php.net">PHP</a>';
preg_match_all('/href="([^"]+)"/', $html, $matches);
// $matches[0] = full matches
// $matches[1] = first capture group contents
foreach ($matches[1] as $url) {
echo $url . "\n";
// https://google.com
// https://php.net
}
?>
preg_replace() — Replace Matched Patterns
<?php
$text = "My phone is 555-123-4567 and backup is 555-987-6543.";
// Replace phone numbers with [REDACTED]
$redacted = preg_replace("/\d{3}-\d{3}-\d{4}/", "[REDACTED]", $text);
echo $redacted;
// My phone is [REDACTED] and backup is [REDACTED].
// Remove extra whitespace
$messy = "This has too many spaces.";
$clean = preg_replace("/\s+/", " ", $messy);
echo $clean; // This has too many spaces.
?>
preg_split() — Split String by Pattern
<?php
$csv = "apple, banana,cherry , date, elderberry";
// Split on comma with optional surrounding whitespace
$fruits = preg_split("/\s*,\s*/", trim($csv));
print_r($fruits);
// Array ( [0] => apple [1] => banana [2] => cherry [3] => date [4] => elderberry )
?>
Practical Examples
Validate a Phone Number
<?php
function isValidPhone(string $phone): bool {
// Matches: (555) 123-4567, 555-123-4567, 5551234567, +1-555-123-4567
return (bool)preg_match("/^(\+1[-\s]?)?(\(?\d{3}\)?[-\s]?)\d{3}[-\s]?\d{4}$/", $phone);
}
var_dump(isValidPhone("555-123-4567")); // true
var_dump(isValidPhone("(555) 123-4567")); // true
var_dump(isValidPhone("+1-555-123-4567")); // true
var_dump(isValidPhone("12345")); // false
?>
Extract All Hashtags from Text
<?php
$tweet = "Loving #PHP and #coding! Best #webdev language. #php8";
preg_match_all("/#(\w+)/i", $tweet, $matches);
$tags = array_map("strtolower", $matches[1]);
$uniqueTags = array_unique($tags);
echo implode(", ", $uniqueTags); // php, coding, webdev, php8
?>
Validate a URL
<?php
function isValidUrl(string $url): bool {
$pattern = "/^(https?:\/\/)?(www\.)?[\w-]+(\.[a-z]{2,})+([\/\w .-]*)*\/?$/i";
return (bool)preg_match($pattern, $url);
}
var_dump(isValidUrl("https://www.example.com")); // true
var_dump(isValidUrl("http://example.com/path/page")); // true
var_dump(isValidUrl("not a url")); // false
?>
Regex Flags
| Flag | Meaning |
|---|---|
i | Case-insensitive matching |
m | Multiline — ^ and $ match start/end of each line |
s | Dot-all — . matches newlines too |
u | Unicode — enables full Unicode support |
Key Points
- PHP uses PCRE regex through functions prefixed with
preg_. preg_match()tests whether a pattern exists and captures groups into a third argument array.preg_match_all()finds every occurrence of a pattern in a string.preg_replace()replaces matched patterns with a replacement string.preg_split()splits a string using a pattern as the delimiter.- Use the
iflag for case-insensitive matching. - Capture groups
()extract specific parts of a match; they are accessible as array elements after the match.
