Em nosso aplicativo, recebemos arquivos de texto ( .txt
,.csv
, etc.) a partir de diversas fontes. Ao ler, esses arquivos às vezes contêm lixo, porque os arquivos foram criados em uma página de código diferente / desconhecida.
Existe uma maneira de (automaticamente) detectar a página de código de um arquivo de texto?
A detectEncodingFromByteOrderMarks
, no StreamReader
construtor, trabalha para UTF8
e outros arquivos unicode marcada, mas eu estou procurando uma maneira de detectar páginas de código, como ibm850
, windows1252
.
Obrigado por suas respostas, foi o que eu fiz.
Os arquivos que recebemos são de usuários finais, eles não têm idéia sobre páginas de código. Os receptores também são usuários finais, a essa altura é o que sabem sobre páginas de código: as páginas de código existem e são irritantes.
Solução:
- Abra o arquivo recebido no bloco de notas, observe um pedaço de texto ilegível. Se alguém se chama François ou algo assim, com sua inteligência humana, você pode adivinhar.
- Criei um aplicativo pequeno que o usuário pode usar para abrir o arquivo e insira um texto que ele saiba que aparecerá no arquivo, quando a página de código correta for usada.
- Passe por todas as páginas de código e exiba as que fornecem uma solução com o texto fornecido pelo usuário.
- Se aparecer mais de uma página de código, peça ao usuário para especificar mais texto.
Se você deseja detectar codificações que não sejam UTF (ou seja, sem BOM), é basicamente uma análise heurística e estatística do texto. Você pode dar uma olhada no documento da Mozilla sobre detecção universal de charset ( mesmo link, com melhor formatação via Wayback Machine ).
fonte
Você já tentou a porta C # para o Mozilla Universal Charset Detector
Exemplo de http://code.google.com/p/ude/
fonte
private Encoding GetEncodingFromString(string encoding) { try { return Encoding.GetEncoding(encoding); } catch { return Encoding.ASCII; } }
Isto é claramente falso. Todo navegador da web possui algum tipo de detector de conjunto de caracteres universal para lidar com páginas que não têm nenhuma indicação de codificação. O Firefox tem um. Você pode baixar o código e ver como ele o faz. Veja alguma documentação aqui . Basicamente, é uma heurística, mas que funciona muito bem.
Dada uma quantidade razoável de texto, é ainda possível detectar o idioma.
Aqui está outro que eu acabei de encontrar usando o Google:
fonte
a character encoding declaration is required even if the encoding is US-ASCII
- uma falta de declaração resulta no uso de um algoritmo heurístico, e não no retorno ao UTF8.Sei que é muito tarde para esta pergunta e esta solução não agradará a alguns (devido ao seu viés centrado no inglês e à falta de testes estatísticos / empíricos), mas funcionou muito bem para mim, especialmente para o processamento de dados CSV enviados:
http://www.architectshack.com/TextFileEncodingDetector.ashx
Vantagens:
Nota: Fui eu quem escreveu esta aula, então, obviamente, leve-a com um pouco de sal! :)
fonte
O Notepad ++ possui esse recurso pronto para uso. Ele também suporta a alteração.
fonte
Procurando uma solução diferente, descobri que
https://code.google.com/p/ude/
essa solução é meio pesada.
Eu precisava de alguma detecção básica de codificação, com base nos 4 primeiros bytes e provavelmente na detecção de conjunto de caracteres xml - por isso, peguei um código-fonte de amostra da Internet e adicionei uma versão ligeiramente modificada do
http://lists.w3.org/Archives/Public/www-validator/2002Aug/0084.html
escrito para Java.
É suficiente ler provavelmente os primeiros 1024 bytes do arquivo, mas estou carregando o arquivo inteiro.
fonte
Se alguém está procurando uma solução de 93,9%. Isso funciona para mim:
fonte
Eu fiz algo semelhante em Python. Basicamente, você precisa de muitos dados de amostra de várias codificações, que são divididas por uma janela deslizante de dois bytes e armazenadas em um dicionário (hash), digitado em pares de bytes, fornecendo valores das listas de codificações.
Dado esse dicionário (hash), você pega seu texto de entrada e:
Se você também já experimentou textos codificados em UTF que não iniciam com nenhuma BOM, a segunda etapa cobrirá as que foram retiradas da primeira etapa.
Até agora, ele funciona para mim (os dados de amostra e os dados de entrada subsequentes são legendas em vários idiomas) com taxas de erro decrescentes.
fonte
A ferramenta "uchardet" faz isso bem usando modelos de distribuição de frequência de caracteres para cada conjunto de caracteres. Arquivos maiores e arquivos "típicos" têm mais confiança (obviamente).
No ubuntu, você apenas
apt-get install uchardet
.Em outros sistemas, obtenha a fonte, o uso e os documentos aqui: https://github.com/BYVoid/uchardet
fonte
brew install uchardet
O construtor da classe StreamReader usa um parâmetro 'detect encoding'.
fonte
Se você pode vincular a uma biblioteca C, pode usar
libenca
. Consulte http://cihar.com/software/enca/ . Na página do manual:É a GPL v2.
fonte
Obteve o mesmo problema, mas ainda não encontrou uma boa solução para detectá-lo automaticamente. Agora estou usando o PsPad (www.pspad.com) para isso;) Funciona bem
fonte
Como se trata basicamente de heurística, pode ser útil usar a codificação de arquivos recebidos anteriormente da mesma fonte que a primeira dica.
A maioria das pessoas (ou aplicativos) faz coisas praticamente na mesma ordem todas as vezes, geralmente na mesma máquina, então é bem provável que quando Bob criar um arquivo .csv e enviá-lo para Mary, ele sempre usará o Windows-1252 ou seja qual for o padrão de sua máquina.
Sempre que possível, um pouco de treinamento do cliente também não prejudica :-)
fonte
Na verdade, eu estava procurando uma maneira genérica, não de programação, de detectar a codificação de arquivo, mas ainda não a encontrei. O que descobri testando com codificações diferentes foi que meu texto era UTF-7.
Então, onde eu estava trabalhando pela primeira vez: StreamReader file = File.OpenText (fullfilename);
Eu tive que alterá-lo para: StreamReader file = new StreamReader (fullfilename, System.Text.Encoding.UTF7);
O OpenText assume que é UTF-8.
você também pode criar o StreamReader como este novo StreamReader (fullfilename, true), o segundo parâmetro que significa que ele deve tentar detectar a codificação a partir da marca de byte do arquivo, mas isso não funcionou no meu caso.
fonte
Abra o arquivo no AkelPad (ou apenas copie / cole um texto ilegível), vá em Editar -> Seleção -> Recodificar ... -> marque "Detecção automática".
fonte
Como complemento para a publicação do ITmeze, usei essa função para converter a saída da porta C # para o Mozilla Universal Charset Detector
MSDN
fonte
Obrigado @ Erik Aronesty por mencionar
uchardet
.Enquanto isso existe o (mesmo?) Ferramenta para linux:
chardet
.Ou, no cygwin, você pode querer usar:
chardetect
.Consulte: página do manual chardet: https://www.commandlinux.com/man-page/man1/chardetect.1.html
Isso detectará heuristicamente (adivinhar) a codificação de caracteres para cada arquivo fornecido e relatará o nome e o nível de confiança da codificação de caracteres detectada em cada arquivo.
fonte
Eu uso esse código para detectar Unicode e a página de código ansi padrão do Windows ao ler um arquivo. Para outras codificações, é necessária uma verificação do conteúdo, manualmente ou por programação. Isso pode ser usado para salvar o texto com a mesma codificação de quando foi aberto. (Eu uso o VB.NET)
fonte
10Y (!) Se passaram desde que isso foi solicitado, e ainda não vejo menção à boa solução da MS, não GPL ': API IMultiLanguage2 .
A maioria das bibliotecas já mencionadas é baseada no UDE da Mozilla - e parece razoável que os navegadores já tenham enfrentado problemas semelhantes. Não sei qual é a solução do chrome, mas desde o IE 5.0 MS os lançamos, e é:
É uma chamada COM nativa, mas aqui está um trabalho muito bom de Carsten Zeumer, que lida com a bagunça de interoperabilidade para o uso de .net. Existem outros por aí, mas em geral essa biblioteca não recebe a atenção que merece.
fonte