php parola regex corrispondenza di confine in utf-8
-
19-09-2019 - |
Domanda
Ho il seguente codice php in un file php utf-8:
var_dump(setlocale(LC_CTYPE, 'de_DE.utf8', 'German_Germany.utf-8', 'de_DE', 'german'));
var_dump(mb_internal_encoding());
var_dump(mb_internal_encoding('utf-8'));
var_dump(mb_internal_encoding());
var_dump(mb_regex_encoding());
var_dump(mb_regex_encoding('utf-8'));
var_dump(mb_regex_encoding());
var_dump(preg_replace('/\bweiß\b/iu', 'weiss', 'weißbier'));
Vorrei l'ultima regex per sostituire solo parole piene e non parti di parole.
Sul mio computer Windows, restituisce:
string 'German_Germany.1252' (length=19)
string 'ISO-8859-1' (length=10)
boolean true
string 'UTF-8' (length=5)
string 'EUC-JP' (length=6)
boolean true
string 'UTF-8' (length=5)
string 'weißbier' (length=9)
Sul web server (Linux), ottengo:
string(10) "de_DE.utf8"
string(10) "ISO-8859-1"
bool(true)
string(5) "UTF-8"
string(10) "ISO-8859-1"
bool(true)
string(5) "UTF-8"
string(9) "weissbier"
In questo modo, l'espressione regolare funziona come mi aspettavo su Windows ma non su Linux.
Quindi, la questione principale è, come devo scrivere il mio regex di corrispondere solo a confini di parola?
A questioni secondarie è come posso lasciare finestre sanno che io voglio usare utf-8 nella mia applicazione PHP.
Soluzione
Anche in modalità UTF-8, abbreviazioni di classe standard come \w
e \b
non sono Unicode-aware. Devi solo usare le abbreviazioni Unicode, come hai lavorato fuori, ma si può rendere un po 'meno brutto utilizzando lookarounds invece di alternanze:
/(?<!\pL)weiß(?!\pL)/u
Si noti anche come Ho lasciato le parentesi graffe fuori delle abbreviazioni di classe Unicode; si può fare quando il nome della classe è costituito da una singola lettera.
Altri suggerimenti
Ecco quello che ho trovato finora. Riscrivendo i modelli di ricerca e sostituzione in questo modo:
$before = '(^|[^\p{L}])';
$after = '([^\p{L}]|$)';
var_dump(preg_replace('/'.$before.'weiß'.$after.'/iu', '$1weiss$2', 'weißbier'));
// Test some other cases:
var_dump(preg_replace('/'.$before.'weiß'.$after.'/iu', '$1weiss$2', 'weiß'));
var_dump(preg_replace('/'.$before.'weiß'.$after.'/iu', '$1weiss$2', 'weiß bier'));
var_dump(preg_replace('/'.$before.'weiß'.$after.'/iu', '$1weiss$2', ' weiß'));
ottengo il risultato voluto:
string 'weißbier' (length=9)
string 'weiss' (length=5)
string 'weiss bier' (length=10)
string ' weiss' (length=6)
sia sul mio computer Windows apache in esecuzione e sul apache in esecuzione ospitato linux webserver.
Presumo ci sia un modo migliore per farlo.
Inoltre, ho ancora vorrei setLocale mio computer Windows per utf-8.
che questo era legato a Bug # 52971
PCRE-meta-caratteri come
\b
\w
che non funziona con stringhe Unicode.
estensione PCRE:. Corretto il bug # 52971 ( PCRE-meta-caratteri non lavorano con utf-8 )
questo commento , cioè un bug in PHP. Ha utilizzando \W
invece di \b
dare alcun beneficio?