Como codificar texto para UTF-8 sem saber de antemão a codificação usada?

1

Eu já vi muitas maneiras de converter texto em UTF-8, mas todas elas precisam especificar a codificação de texto atual usada.

Existe uma maneira de converter vários arquivos em UTF-8 sem ter que se preocupar com o que eles usavam antes?

    
por Freedo 31.10.2017 / 13:35

1 resposta

3

Este é um problema difícil, mas eu o tenho com muita frequência. Eu construí um conjunto de scripts com diferentes abordagens e vou mostrar um simples (ensureutf8 no contexto latino europeu)

  • para cada arquivo, pergunte por seu tipo e charset ( file -i )
  • decida o que fazer para casos comuns, mantendo um backup.
  • em muitos casos ... não faça nada!
  • em alguns casos, use um padrão (no exemplo CP1252 / latin1)
#!/usr/bin/perl
use strict;
my $charset;

for(@ARGV){
  $charset="?";
  next if /.bak$/;
  my $type = 'file -b -i '$_'';   ### use file -i for  charset and type
  if($type =~ /(\S+);\s+charset=(\S+)/){$type=$1; $charset=lc($2)};

  next    if($charset eq "utf-8") ;
  next    if($charset eq "binary") ;
  next    if($charset eq "us-ascii")  ;
  next    if($type eq "application/postscript");

  if($type eq "application/xml"){
    rename($_ ,"$_.bak");
    system ("xmllint --encode utf-8 '$_.bak' > '$_'\n")  }
  elsif($charset eq "non-iso" or $charset eq "unknown-8bit" ) {
    rename($_ ,"$_.bak");
    system ("iconv -f CP1252 -t utf-8 '$_.bak' > '$_'\n")  }  ## DANGER
  elsif($charset eq "utf-16le"){
    rename($_ ,"$_.bak");
    system ("iconv -f $charset  -t utf-8 '$_.bak' > '$_'\n")  }
  elsif($charset eq "iso-8859"  or  $charset eq "iso-8859-1"){
    rename($_ ,"$_.bak");
    system ("iconv -f latin1 -t utf-8 '$_.bak' > '$_'\n")  }
  else { print "HELP: '$type:$charset' '$_'\n"; }
}

Esta não é uma ferramenta universal, mas pode ser útil como ponto de partida para implementar sua própria heurística.

    
por 31.10.2017 / 15:16