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.

È stato utile?

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.

e fissato in PHP 5.3.4

  

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?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top