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

TokenMeaning
\dAny digit (0-9)
\wAny "word" character (letters, digits, underscore)
\sAny 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.

Example: /[6-9]\d{9}/ matches a 10-digit Indian mobile number.
Submit the form above to see real, live 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

IssueProblemFix
Forgetting delimiterspreg_* functions throw an error without themWrap the pattern, e.g. /pattern/
Not handling invalid patternsRaw PHP warnings shown to usersSuppress with @ and check preg_last_error()
Using regex for simple substring checksSlower and harder to readUse str_contains() / strpos() when there's no real pattern
Greedy quantifiers on HTMLMatches too much textUse a proper HTML parser (e.g. DOMDocument) instead of regex for HTML
Next: Continue with Date & Time - formatting, parsing, and working with timezones in PHP.