Saltar al contenido

¿Cómo eliminar los caracteres malos que no son adecuados para la codificación utf8 en MySQL?

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+FFFDcará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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *