PCRE Patterns

PCRE Patterns, Delimiters and Modifiers

The preg_* functions run PCRE2 (10.46 on Ubuntu 26.04 225 ). A pattern has a delimiter at each end and modifiers after it: '/^\d+$/u'. Use # or ~ when the pattern holds slashes, and single quotes so PHP leaves backslashes alone. The syntax largely matches JavaScript's, plus \p{L} properties and, since PHP 8.4 bundled PCRE2 10.44, the {,3} quantifier.

The pattern modifiers
Modifier Effect
i m s Ignore case; ^ $ per line; . matches newlines
x u Allow spaces and comments; treat text as UTF-8
U D A Ungreedy; $ only at the end; anchored start
n (8.2) r (8.4) Only named groups capture; with iu, keep ASCII and non-ASCII apart
Delimiters, modifiers and an extended pattern with named groups (pcre.php)PHP
<?php
echo PCRE_VERSION, ' ', preg_match('#^/books/\d+$#', '/books/42'), ' ',
    preg_match('/^émile$/i', 'Émile'), preg_match('/^émile$/iu', 'Émile'), ' ',
    preg_match('/^\w+$/', 'café'), preg_match('/^\w+$/u', 'café'), "\n";
$k = "\u{212A}elvin";                                // starts with U+212A KELVIN SIGN
echo preg_match('/^kelvin$/iu', $k), preg_match('/^kelvin$/iur', $k), ' ',
    preg_match('/^a{,3}$/', 'aa'), ' ', preg_match("/^.+$/", "a\nb"),
    preg_match("/^.+$/s", "a\nb"), ' ', preg_match_all('/^\d/m', "1a\n2b\nc"), "\n";
$price = '~ (?<cur> [$€£] ) \s* (?<amt> \d{1,3} (?: ,\d{3} )* (?: \.\d{2} )? ) ~xu';
preg_match($price, 'Total: € 1,299.00', $m);
echo $m['cur'], ' ', $m['amt'], ' | ', preg_quote('a.b+c', '/'), "\n";
Output
10.46 2025-08-27 1 01 01
10 1 01 2
€ 1,299.00 | a\.b\+c

Each digit pair is a pattern without and with a modifier: without u, i cannot fold É and \w misses é; without r the Kelvin sign matches k. The x pattern reads like a grammar, with (?<name>...) groups. Run user input through preg_quote() before splicing it in. A broken pattern returns false with a compile warning, while preg_last_error_msg() says only "Internal error".