Any ideas why this preg_match works up to PHP7.2 but fails with 7.3+ ?
$word = 'umweltfreundilch'; //real life example :/
preg_match('/^(?U)(.*(?:[aeiouyäöü])(?:[^aeiouyäöü]))(?X)(.*)$/u', $word, $matches);
var_dump($matches);
Warning: preg_match(): Compilation failed: unrecognized character after (? or (?-
PHP 7.2 and below output:
array(3) {
[0]=>
string(16) "umweltfreundilch"
[1]=>
string(2) "um"
[2]=>
string(14) "weltfreundilch"
}
RegEx seems to be ok, doesn't it?
https://regex101.com/r/LGdhaM/1
Like PHP, many other programming languages have their own implementation of regular expressions. This is the same with other applications also, which have their own support of regexes having various syntaxes.
PHP 7.4 is the latest stable version of PHP. It was released on November 28, 2019 and it's the last version before PHP 8. It brings lots of new features, syntax additions and fixes.
preg_match() in PHP – this function is used to perform pattern matching in PHP on a string. It returns true if a match is found and false if a match is not found. preg_split() in PHP – this function is used to perform a pattern match on a string and then split the results into a numeric array.
++ From What is double plus in regular expressions? That's a Possessive Quantifier. It basically means that if the regex engine fails matching later, it will not go back and try to undo the matches it made here.
In PHP 7.3 and later, the Perl-Compatible Regular Expressions (PCRE) extension was upgraded to PCRE2.
The PCRE2 syntax documentation does not list (?X)
as an available inline modifier option. Here are the supported options:
(?i) caseless
(?J) allow duplicate named groups
(?m) multiline
(?n) no auto capture
(?s) single line (dotall)
(?U) default ungreedy (lazy)
(?x) extended: ignore white space except in classes
(?xx) as (?x) but also ignore space and tab in classes
(?-...) unset option(s)
(?^) unset imnsx options
However, you may actually use X
flag after the trailing delimiter:
preg_match('/^(?U)(.*[aeiouyäöü][^aeiouyäöü])(.*)$/Xu', $word, $matches)
See PHP 7.4 demo.
To cancel (?U)
effect, you may use either of the two options: a (?-U)
inline modifier, like in
preg_match('/^(?U)(.*[aeiouyäöü][^aeiouyäöü])(?-U)(.*)$/u', $word, $matches);
// ^^^^^
Or, enclose the affected patterns into a (?U:...)
modifier group:
preg_match('/^(?U:(.*[aeiouyäöü][^aeiouyäöü]))(.*)$/u', $word, $matches);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
See more about changes to regex handling in PHP 7.3+ in preg_match(): Compilation failed: invalid range in character class at offset.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With