RegEx falhando desde PHP 7.4, funcionando em 7.3
Alguma idéia de por que este preg_match funciona até PHP7.2, mas falha com 7.3+?
$word = 'umweltfreundilch'; //real life example :/ preg_match('/^(?U)(.*(?:[aeiouyäöü])(?:[^aeiouyäöü]))(?X)(.*)$/u', $word, $matches);
var_dump($matches);
Aviso: preg_match (): Falha na compilação: caractere não reconhecido após (? Ou (? -
Resultado do PHP 7.2 e abaixo:
array(3) {
[0]=>
string(16) "umweltfreundilch"
[1]=>
string(2) "um"
[2]=>
string(14) "weltfreundilch"
}
RegEx parece estar bem, não é?
https://regex101.com/r/LGdhaM/1
Respostas
No PHP 7.3 e posterior, a extensão Perl-Compatible Regular Expressions (PCRE) foi atualizada para PCRE2.
A documentação da sintaxe PCRE2 não é listada(?X) como uma opção de modificador embutido disponível. Aqui estão as opções com suporte:
(?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
No entanto, você pode realmente usar o Xsinalizador após o delimitador final:
preg_match('/^(?U)(.*[aeiouyäöü][^aeiouyäöü])(.*)$/Xu', $word, $matches)
Veja a demonstração do PHP 7.4 .
Para cancelar o (?U)efeito, você pode usar uma das duas opções: um (?-U)modificador embutido, como em
preg_match('/^(?U)(.*[aeiouyäöü][^aeiouyäöü])(?-U)(.*)$/u', $word, $matches);
// ^^^^^
Ou coloque os padrões afetados em um (?U:...)grupo de modificadores:
preg_match('/^(?U:(.*[aeiouyäöü][^aeiouyäöü]))(.*)$/u', $word, $matches);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Veja mais sobre as mudanças na manipulação de regex no PHP 7.3+ em preg_match (): Falha na compilação: intervalo inválido na classe de caractere no deslocamento .