Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como remover caracteres ruins que não são adequados para codificação utf8 no MySQL?


Quando tive problemas como esse, usei o script Perl para garantir que os dados fossem convertidos em UTF-8 válido usando um código como este:
use Encode;
binmode(STDOUT, ":utf8");
while (<>) {
    print Encode::decode('UTF-8', $_);
}

Este script leva (possivelmente corrompido) UTF-8 em stdin e reimprime UTF-8 válido para stdout . Caracteres inválidos são substituídos por (U+FFFD , caractere de substituição Unicode ).

Se você executar este script em uma boa entrada UTF-8, a saída deverá ser idêntica à entrada.

Se você tiver dados no banco de dados, faz sentido usar o DBI para verificar sua(s) tabela(s) e limpar todos os dados usando essa abordagem para garantir que tudo seja UTF-8 válido.

Esta é a versão Perl de uma linha deste mesmo script:
perl -MEncode -e "binmode STDOUT,':utf8';while(<>){print Encode::decode 'UTF-8',\$_}" < bad.txt > good.txt

EDIT:Adicionada solução somente Java .

Este é um exemplo de como fazer isso em 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: Пр?вет
    }
}