2010-12-27 22 views
6

¿Hay alguna forma en PHP de detectar el siguiente carácter ?Detección de caracteres " " desconocida Unicode en PHP

Actualmente estoy solucionando un número de problemas de codificación UTF-8 con algunos algoritmos diferentes y necesito poder detectar si está presente en una cadena. ¿Cómo lo hago con strpos?

Simplemente pegar el caracter en mi base de código no parece funcionar.

if (strpos($names['decode'], '?') !== false || strpos($names['decode'], '�') !== false) 
+0

tratan � en lugar de –

+0

Desafortunadamente no. – James

+1

Este es el enfoque equivocado. Debería agregar más información acerca de lo que está haciendo, probablemente haya mejores formas de hacer lo que quiera –

Respuesta

15

La conversión de una cadena UTF-8 en UTF-8 utilizando iconv() utilizando el parámetro //IGNORE produce un resultado donde los caracteres UTF-8 no válidos se eliminan.

Por lo tanto, puede detectar un carácter roto comparando la longitud de la cadena antes y después de la operación iconv. Si difieren, contenían un carácter roto.

caso de prueba (asegúrese de guardar el archivo como UTF-8):

<?php 

header("Content-type: text/html; charset=utf-8"); 

$teststring = "Düsseldorf"; 

// Deliberately create broken string 
// by encoding the original string as ISO-8859-1 
$teststring_broken = utf8_decode($teststring); 

echo "Broken string: ".$teststring_broken ; 

echo "<br>"; 

$teststring_converted = iconv("UTF-8", "UTF-8//IGNORE", $teststring_broken); 

echo $teststring_converted; 

echo "<br>"; 

if (strlen($teststring_converted) != strlen($teststring_broken )) 
echo "The string contained an invalid character"; 

en teoría, se podría caer //IGNORE y simplemente prueba para un fallido (vacío) iconv operación, pero puede haber otros razones para que un ícono falle solo caracteres inválidos ... No lo sé. Usaría el método de comparación.

+0

Genius :) ¡Gracias! – James

+1

Tenga en cuenta que la opción '" // IGNORE "' [puede fallar en las versiones recientes de la biblioteca libiconv] (http://www.php.net/manual/en/function.iconv.php#108643), pero puede utilice esta solución alternativa: 'ini_set ('mbstring.substitute_character'," none "); $ teststring_converted = mb_convert_encoding ($ string, 'UTF-8', 'UTF-8'); ' – Adam

1

Por lo que yo sé, que el símbolo de interrogación no es un solo carácter. Hay muchos códigos de caracteres diferentes en los conjuntos de fuentes estándar que no están asignados a un símbolo, y ese es el símbolo predeterminado que se utiliza. Para hacer la detección en PHP, primero necesita saber qué tipo de letra está usando. Luego, debe observar la implementación de fuentes y ver qué rangos de códigos asignan al "?" símbolo, y luego ver si el personaje dado está en uno de esos rangos.

+1

En realidad, es un personaje en particular: es U + FFFD, "Carácter de reemplazo de Unicode": puede ocurrir cuando algún sistema no pudo decodificar los datos en ese punto (y lo reemplazó con ese carácter) o si simplemente no lo hace tener la fuente. Es mejor mirar los datos y ver qué datos tienes en realidad. – Thanatos

+0

Supongo que eso es lo que quise decir con "rangos" de datos que no se decodifican correctamente. – Reinderien

3

Aquí es lo que hago para detectar y corregir la codificación de las cadenas no codificados en UTF-8 cuando eso es lo que estoy esperando:

$encoding = mb_detect_encoding($str, 'utf-8, iso-8859-1, ascii', true); 
    if (strcasecmp($encoding, 'UTF-8') !== 0) { 
     $str = iconv($encoding, 'utf-8', $str); 
    } 
0

uso el método personalizado (usando str_replace) para desinfectar indefinido personajes:

$input='a³'; 

    $text=str_replace("\n\n", "sample000"  ,$text); 
    $text=str_replace("\n", "sample111"  ,$text); 

    $text=filter_var($text,FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_STRIP_LOW); 

    $text=str_replace("sample000", "<br/><br/>" ,$text); 
    $text=str_replace("sample111", "<br/>"  ,$text); 

    echo $text; //outputs ------------> a3