Luego de de una prolongada selección de datos dimos con la respuesta este asunto que presentan algunos de nuestros usuarios. Te regalamos la solución y deseamos servirte de gran ayuda.
Solución:
Cuando tuve un problema como este, usé el script Perl para asegurar que los datos se conviertan a UTF-8 válido usando un código como este:
use Encode;
binmode(STDOUT, ":utf8");
while (<>)
print Encode::decode('UTF-8', $_);
Este script toma (posiblemente corrupto) UTF-8 en stdin
y reimprime UTF-8 válido para stdout
. Los caracteres no válidos se reemplazan con (
U+FFFD
carácter de reemplazo Unicode).
Si ejecuta este script en una buena entrada UTF-8, la salida debería ser idéntica a la entrada.
Si tiene datos en la base de datos, tiene sentido usar DBI para escanear sus tablas y borrar todos los datos usando este enfoque para asegurarse de que todo sea UTF-8 válido.
Esta es la versión Perl de una sola línea de este mismo script:
perl -MEncode -e "binmode STDOUT,':utf8';while(<>)print Encode::decode 'UTF-8',$_" < bad.txt > good.txt
EDITAR: Se agregó una solución solo para Java.
Este es un ejemplo de cómo hacer esto en Java:
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
public class UtfFix
public static void main(String[] args) throws InterruptedException, CharacterCodingException
CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
decoder.onMalformedInput(CodingErrorAction.REPLACE);
decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
ByteBuffer bb = ByteBuffer.wrap(new byte[]
(byte) 0xD0, (byte) 0x9F, // 'П'
(byte) 0xD1, (byte) 0x80, // 'р'
(byte) 0xD0, // corrupted UTF-8, was 'и'
(byte) 0xD0, (byte) 0xB2, // 'в'
(byte) 0xD0, (byte) 0xB5, // 'е'
(byte) 0xD1, (byte) 0x82 // 'т'
);
CharBuffer parsed = decoder.decode(bb);
System.out.println(parsed);
// this prints: Пр?вет
Puede codificarlo y luego decodificarlo a/desde UTF-8:
String label = "look into my eyes 〠.〠";
Charset charset = Charset.forName("UTF-8");
label = charset.decode(charset.encode(label)).toString();
System.out.println(label);
producción:
look into my eyes ?.?
editar: creo que esto solo podría funcionar en Java 6.
Puede filtrar caracteres sustitutos con esta expresión regular:
String str = ""; //U+20000, represented by 2 chars in java (UTF-16 surrogate pair)
str = str.replaceAll( "([\ud800-\udbff\udc00-\udfff])", "");
System.out.println(str.length()); //0
Sección de Reseñas y Valoraciones
Recuerda algo, que tienes la capacidad de esclarecer tu experiencia si te fue de ayuda.