2012-04-28 2 views
5

Это моя проблема: Мой язык (португальский) использует кодировку символов ISO-8859-1! Когда я хочу получить доступ символ из строки, как «Coração» (сердце) я использую:Есть простой способ получить символ из многобайтовой строки в 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/>"; 

Это дает:

 
c 
o 
r 
a 
ç 
ã 
o 

Это прекрасно работает ... Но мой вопрос, если использование Функция mb_substr не является быстрой, как простой стандартный доступ к строке! Но я хочу простой способ сделать это ... как в обычном доступе к строковым символам: echo $ str [$ pos] .... Это возможно?

ответ

0

... вид. Если вы используете кодировку с фиксированной шириной (ISO 8859- *, UCS-2 или UTF-32 или UTF-16 в BMP), вы можете использовать фиксированный множитель для доступа к символам. Тем не менее, вам все равно придется делать множественный доступ для многобайтовых кодировок.

+0

Ну ... Но мой вопрос о эффективном способе сделать эти доступы. Я проверил обычный цикл конкатенации строк ($ new_str. = $ Old_str [2] - только для тестирования ...) и используя mb_substr ($ new_str. = Mb_substr ($ old_str, 2, 1, 'UTF-8') и I получил (с петлей 50 000 итераций): 0,016 с обычного доступа против 4.9802091121674 с функцией mb_substr! Это большая проблема с производительностью! –

+0

С кодировкой с фиксированной шириной вы можете использовать фиксированный множитель. –

+0

Как я мог это сделать? Покажите мне пример! –

4

Функция mb_substr не работает как [...] как в обычном символьном доступе символов: echo $ str [$ pos] .... Это возможно?

No.

Функция многобайтовой должна проверить каждый символ, чтобы определить, сколько байт (1 к 4 в UTF-8) он занимает. Там у вас сразу есть причина, почему индексация символов ($a[n]) не будет работать: вы не знаете, какие байты вам нужны, чтобы получить n-й символ, прежде чем вы прочитаете все символы до этого.

Чтобы ускорить процесс немного, вы можете посмотреть на ответы здесь: How to iterate UTF-8 string in PHP?

Однако, так как вы используете ISO 8859-1 или Latin-1, вы не должны использовать mb_ функции на всех , так как в этой кодировке все символы: encoded in one byte.

+0

Упрощенный. ответы на предоставленную ссылку, [этот] (http://stackoverflow.com/a/14366023/793036) и [мой ответ] (http://stackoverflow.com/a/17156392/793036), если у вас есть mbstring. func_overload, установленный в 7, - это то, что вы хотите. Они в основном делают индексацию, если она доступна, и используют медленные mb_subs tr только при необходимости. В примере OP это потребует только mb_substr один раз. – Andrew

+0

Благодарим вас за полезные ссылки и пояснения. 5 лет спустя, по-прежнему наиболее релевантный ответ. – Valdrinit

1

Try:

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