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.
| 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 |
<?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";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".