2012-04-28 12 views
5

Este es mi problema: ¡Mi idioma (portugués) usa la codificación de caracteres ISO-8859-1! Cuando quiero acceder a un personaje de una cadena como 'coração' (corazón) yo uso:¿Hay una manera simple de obtener un carácter de una cadena multibyte en 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/>"; 

Esto produce:

 
c 
o 
r 
a 
ç 
ã 
o 

Esto funciona bien ... Pero mi problema es si el uso de ¡La función mb_substr no es tan rápida como el acceso normal a una cadena simple! Pero quiero una manera simple de hacer esto ... como en el acceso normal de caracteres de cadena: echo $ str [$ pos] .... ¿Es posible?

Respuesta

0

... Más o menos. Si usa una codificación de ancho fijo (ISO 8859- *, UCS-2 o UTF-32, o UTF-16 dentro de BMP), entonces puede usar un multiplicador fijo para acceder a los caracteres. Sin embargo, aún necesitará hacer múltiples accesos para las codificaciones de bytes múltiples.

+0

Bueno ... Pero mi pregunta es acerca de una forma eficiente de hacer estos accesos. Probé un ciclo normal de concatenación de cadenas ($ new_str. = $ Old_str [2] - solo para probar ...) y usando mb_substr ($ new_str. = Mb_substr ($ old_str, 2, 1, 'UTF-8') y yo obtuve esto (con bucle de 50 000 iteraciones): 0.016 s al acceso normal contra 4.9802091121674 s a la función mb_substr! Es un gran problema de rendimiento! –

+0

Con una codificación de ancho fijo puede usar un multiplicador fijo. –

+0

¿Cómo podría hacer esto entonces? Muéstrame un ejemplo! –

4

La función mb_substr no es [...] rápida como en el acceso normal de caracteres de cadena: echo $ str [$ pos] .... ¿Es posible?

No.

Las funciones de varios bytes tienen que comprobar cada carácter para determinar cuántos bytes (de 1 a 4 en UTF-8) que ocupa. Ahí tienes la razón por la cual la indexación de caracteres ($a[n]) no funcionará: no sabes qué byte (s) necesitas para obtener el n antes de haber leído todos los caracteres anteriores a ese.

para acelerar las cosas un poco, se puede ver en las respuestas aquí: How to iterate UTF-8 string in PHP?

Sin embargo, ya que utiliza la norma ISO 8859-1 o Latín-1, usted no tiene que utilizar las funciones mb_ en absoluto , ya que en esa codificación, todos los caracteres son encoded in one byte.

+0

Upvoted. respuestas en el enlace proporcionado, [este]] (http://stackoverflow.com/a/14366023/793036) y [mi respuesta] (http://stackoverflow.com/a/17156392/793036) si tiene mbstring. func_overload establecido en 7, es lo que quieres. Básicamente hacen la indexación si está disponible y usan los archivos mb_subs lentos tr solo si es necesario. En el ejemplo de OP, solo requerirá mb_substr una vez. – Andrew

+0

Gracias por los útiles enlaces y explicaciones proporcionadas. 5 años después, sigue siendo la respuesta más relevante. – Valdrinit

1

Probar:

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