UTF-8 puede almacenar cualquier caracter Unicode. Si su codificación es otra cosa, incluyendo ISO-8859-1 o Windows-1252, UTF-8 puede almacenar cada carácter en ella. Por lo tanto, no tiene que preocuparse por perder ningún carácter al convertir una cadena de cualquier otra codificación a UTF-8.
Además, tanto ISO-8859-1 como Windows-1252 son codificaciones de un solo byte donde cualquier byte es válido. No es técnicamente posible distinguir entre ellos. Elegiría Windows-1252 como su coincidencia predeterminada para secuencias que no sean UTF-8, ya que los únicos bytes que decodifican de manera diferente son el rango 0x80-0x9F. Estos decodifican a varios personajes como comillas inteligentes y al euro en Windows-1252, mientras que en ISO-8859-1 son caracteres de control invisibles que casi nunca se usan. Los navegadores web a veces dicen que están usando ISO-8859-1, pero a menudo usarán Windows-1252.
sería el código asegurar que una cadena es seguro para insertar en un documento codificado en UTF-8
seguramente querrá para establecer el parámetro opcional ‘estricta’ TRUE para este propósito. Pero no estoy seguro de que esto realmente cubra todas las secuencias UTF-8 no válidas. La función no pretende verificar una secuencia de bytes para la validez UTF-8 explícitamente. Se han conocido casos en los que mb_detect_encoding adivinaría incorrectamente el UTF-8 anteriormente, aunque no sé si aún puede suceder en modo estricto.
Si usted quiere estar seguro, hágalo usted mismo usando el W3-recommended regex:
if (preg_match('%^(?:
[\x09\x0A\x0D\x20-\x7E] # ASCII
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
)*$%xs', $string))
return $string;
else
return iconv('CP1252', 'UTF-8', $string);
Muchas gracias. Sé que los desarrolladores siempre comentan sobre la lentitud de las expresiones regulares. ¿Cuán cuidadoso debería estar usando esto en grandes loops con mucho texto? Por ejemplo, un ciclo que itera 200 veces y limpia el texto de 10.000 caracteres en cada iteración. – Brian
Si bien no soy partidario de regex, en este caso no debería ser tan malo. Regex se vuelve lento cuando tienes secuencias sucesivas o anidadas '?'/'*'/'+' Que pueden hacer que tenga que retroceder buscando diferentes formas de hacer coincidir. Eso no sucederá en este caso. – bobince
Excelente. Entonces, cuando use iconv como usted describe arriba, si especifico CP1252 como el conjunto de caracteres de entrada, y la cadena es algo distinto a CP1252 o ISO-8859-1, devolverá una cadena segura UTF-8, aunque algunos caracteres pueden perderse. ¿Es eso correcto? – Brian