2012-04-28 19 views
5

Oto mój problem: Mój język (portugalski) używa kodowania znaków ISO-8859-1! Gdy chcę przejść znak z łańcucha jak „Coracao” (serce) używam:Istnieje prosty sposób na uzyskanie znaku z ciągu wielobajtowego w PHP?

mb_internal_encoding('ISO-8859-1'); 
$str = "coração"; 

$len = mb_strlen($str,'UTF-8'); 

for($i=0;$i<$len;++$i) 
    echo mb_substr($str, $i, 1, 'UTF-8')."<br/>"; 

ta produkuje:

 
c 
o 
r 
a 
ç 
ã 
o 

Działa to dobrze ... Ale mój problem jest wtedy, gdy wykorzystanie Funkcja mb_substr nie jest szybka jak zwykły dostęp do zwykłego ciągu! Ale chcę prosty sposób to zrobić .... jak w normalnym dostępie znaków ciąg: echo $ str [$ pos] .... Jest to możliwe?

Odpowiedz

0

... Sortuj. Jeśli używasz kodowania o stałej szerokości (ISO 8859- *, UCS-2 lub UTF-32 lub UTF-16 w BMP), możesz użyć stałego mnożnika dla dostępu do postaci. Nadal będziesz musiał wykonać wiele dostępów dla kodowania wielobajtowego.

+0

Cóż ... Ale moje pytanie jest o skuteczny sposób wykonać te dostępy. Przetestowałem normalną ciągłą pętlę konkatenacji ($ new_str. = $ Old_str [2] - tylko do testowania ...) i używając mb_substr ($ new_str. = Mb_substr ($ old_str, 2, 1, 'UTF-8') i I mam to (z pętlą 50 000 iteracji): 0.016 s do normalnego dostępu do 4.9802091121674 s do funkcji mb_substr! To jest poważny problem z wydajnością –

+0

Przy kodowaniu ze stałą szerokością można użyć stałego mnożnika –

+0

Jak mogłem to zrobić? Pokaż mi przykład! –

4

Funkcja mb_substr nie jest szybka jak [...] jak w zwykłym dostępie znaków znakowych: echo $ str [$ pos] .... Jest to możliwe?

nr

Funkcje wielobajtowe trzeba sprawdzić każdy znak, aby określić, ile bajtów (od 1 do 4 w UTF-8) zajmuje. Natychmiast pojawi się powód, dla którego indeksowanie znaków ($a[n]) nie zadziała: nie wiesz, ile bajtów potrzebujesz, aby uzyskać znak przed przeczytaniem wszystkich znaków przed nim.

Aby przyspieszyć nieco, można spojrzeć na odpowiedzi tutaj: How to iterate UTF-8 string in PHP?

Ponieważ jednak użyć ISO 8859-1 lub Latin-1, nie trzeba korzystać z funkcji mb_ w ogóle , ponieważ w tym kodowaniu wszystkie znaki są encoded in one byte.

+0

Przełomowy. odpowiedzi na podany link, [ten] (http://stackoverflow.com/a/14366023/793036) i [moja odpowiedź] (http://stackoverflow.com/a/17156392/793036) jeśli masz mbstring. func_overload ustawione na 7, są tym, czego potrzebujesz. Zasadniczo robią indeksowanie, jeśli są dostępne i używają powolnego mb_subs tr tylko w razie potrzeby. W przykładzie OP wymaga to tylko raz mb_substr. – Andrew

+0

Dziękujemy za przydatne linki i wyjaśnienia. 5 lat później, wciąż najbardziej trafna odpowiedź. – Valdrinit

1

Spróbuj:

preg_match_all("/./u", $str, $ar_chars); 
print_r($ar_chars);