PHP Regular Expressions
Regular expressions (regex) describe a pattern of text so you can test, find, or
replace matches without writing character-by-character logic. PHP's preg_*
functions (PCRE - Perl Compatible Regular Expressions) are the standard tool for this.
The regex syntax itself isn't PHP-specific - the same patterns work in JavaScript, Python,
and most other languages.
1) preg_match() - Test for a Match
preg_match($pattern, $subject, $matches) returns 1 if the
pattern matches, 0 if it doesn't, or false on error. Parenthesized
groups in the pattern are captured into $matches.
<?php
$email = "sonu@example.com";
if (preg_match('/^([\w.-]+)@([\w.-]+)$/', $email, $matches)) {
echo "Username: " . $matches[1]; // sonu
echo "Domain: " . $matches[2]; // example.com
}
?>
2) preg_match_all() - Find Every Match
preg_match_all() finds all matches in a string, not just the first.
It returns the number of matches found, and fills $matches[0] with every
matched substring.
<?php
$text = "Call 9876543210 or 8123456789";
preg_match_all('/[6-9]\d{9}/', $text, $matches);
print_r($matches[0]); // ['9876543210', '8123456789']
?>
3) preg_replace() - Find and Replace
<?php
$text = "Visit http://old-site.com today";
$clean = preg_replace('/http:\/\//', 'https://', $text);
echo $clean; // Visit https://old-site.com today
?>
4) preg_split() - Split by a Pattern
explode() only splits on a fixed string. preg_split() splits on
anything matching a pattern - useful when your separators vary.
<?php
$text = "PHP, MySQL; HTML , jQuery";
$parts = preg_split('/\s*[,;]\s*/', $text);
print_r($parts); // ['PHP', 'MySQL', 'HTML', 'jQuery']
?>
5) Common Regex Tokens
| Token | Meaning |
|---|---|
\d | Any digit (0-9) |
\w | Any "word" character (letters, digits, underscore) |
\s | Any whitespace character |
+ | One or more of the previous token |
* | Zero or more of the previous token |
? | Zero or one of the previous token |
^ | Start of the string (or line, with the m flag) |
$ | End of the string (or line, with the m flag) |
6) Live Demo: Regex Tester
Enter a pattern (including the delimiters, e.g. /[6-9]\d{9}/) and a test
string, then submit. This form posts back to this same page, and the PHP code at the top
of this file runs a real preg_match_all() against your input.
preg_match_all() results.<?php
// Suppress the warning a bad pattern would raise, and check preg_last_error()
$result = @preg_match_all($pattern, $subject, $found);
if ($result === false || preg_last_error() !== PREG_NO_ERROR) {
// preg_last_error_msg() needs PHP 8+; on PHP 7 map the code yourself
echo "Invalid pattern (code " . preg_last_error() . ")";
} else {
$matches = $found[0]; // list of matched strings
}
?>
7) Best Practices & Common Mistakes
| Issue | Problem | Fix |
|---|---|---|
| Forgetting delimiters | preg_* functions throw an error without them | Wrap the pattern, e.g. /pattern/ |
| Not handling invalid patterns | Raw PHP warnings shown to users | Suppress with @ and check preg_last_error() |
| Using regex for simple substring checks | Slower and harder to read | Use str_contains() / strpos() when there's no real pattern |
| Greedy quantifiers on HTML | Matches too much text | Use a proper HTML parser (e.g. DOMDocument) instead of regex for HTML |