En nuestra aplicación, recibimos archivos de texto ( .txt
,.csv
, etc.) a partir de diversas fuentes. Al leer, estos archivos a veces contienen basura porque los archivos se crearon en una página de códigos diferente / desconocida.
¿Hay alguna manera de detectar (automáticamente) la página de códigos de un archivo de texto?
El detectEncodingFromByteOrderMarks
, por el StreamReader
constructor, trabaja para UTF8
y otros archivos Unicode marcada, pero estoy buscando una manera de detectar las páginas de códigos, como ibm850
, windows1252
.
Gracias por sus respuestas, esto es lo que he hecho.
Los archivos que recibimos son de usuarios finales, no tienen idea de las páginas de códigos. Los receptores también son usuarios finales, por ahora esto es lo que saben sobre las páginas de códigos: las páginas de códigos existen y son molestas.
Solución:
- Abra el archivo recibido en el Bloc de notas, mire un texto confuso. Si alguien se llama François o algo así, con tu inteligencia humana puedes adivinar esto.
- He creado una pequeña aplicación que el usuario puede usar para abrir el archivo e ingresar un texto que el usuario sabe que aparecerá en el archivo cuando se use la página de códigos correcta.
- Recorra todas las páginas de códigos y muestre las que dan una solución con el texto proporcionado por el usuario.
- Si aparece más de una página de códigos, solicite al usuario que especifique más texto.
Si está buscando detectar codificaciones que no sean UTF (es decir, sin BOM), básicamente se debe a la heurística y al análisis estadístico del texto. Es posible que desee echar un vistazo al documento de Mozilla sobre detección universal de juegos de caracteres ( mismo enlace, con mejor formato a través de Wayback Machine ).
fuente
¿Has probado el puerto C # para Mozilla Universal Charset Detector?
Ejemplo de http://code.google.com/p/ude/
fuente
private Encoding GetEncodingFromString(string encoding) { try { return Encoding.GetEncoding(encoding); } catch { return Encoding.ASCII; } }
Esto es claramente falso. Cada navegador web tiene algún tipo de detector universal de caracteres para manejar páginas que no tienen ninguna indicación de codificación. Firefox tiene uno. Puede descargar el código y ver cómo lo hace. Vea alguna documentación aquí . Básicamente, es una heurística, pero que funciona muy bien.
Dada una cantidad razonable de texto, incluso es posible detectar el idioma.
Aquí hay otro que acabo de encontrar usando Google:
fuente
a character encoding declaration is required even if the encoding is US-ASCII
, una declaración deficiente resulta en el uso de un algoritmo heurístico, no en retroceder a UTF8.Sé que es muy tarde para esta pregunta y esta solución no será atractiva para algunos (debido a su sesgo centrado en el inglés y su falta de pruebas estadísticas / empíricas), pero me funcionó muy bien, especialmente para procesar datos CSV cargados:
http://www.architectshack.com/TextFileEncodingDetector.ashx
Ventajas:
Nota: Yo escribí esta clase, ¡así que obviamente tómalo con un grano de sal! :)
fuente
Notepad ++ tiene esta característica lista para usar. También admite cambiarlo.
fuente
Buscando una solución diferente, encontré que
https://code.google.com/p/ude/
Esta solución es un poco pesada.
Necesitaba algo de detección de codificación básica, basada en 4 primeros bytes y probablemente detección de juego de caracteres xml, así que tomé un código fuente de muestra de Internet y agregué una versión ligeramente modificada de
http://lists.w3.org/Archives/Public/www-validator/2002Aug/0084.html
escrito para Java
Es suficiente para leer probablemente los primeros 1024 bytes del archivo, pero estoy cargando el archivo completo.
fuente
Si alguien está buscando una solución del 93.9%. Esto funciona para mi:
fuente
He hecho algo similar en Python. Básicamente, necesita muchos datos de muestra de varias codificaciones, que se desglosan en una ventana deslizante de dos bytes y se almacenan en un diccionario (hash), codificados en pares de bytes que proporcionan valores de listas de codificaciones.
Dado ese diccionario (hash), toma su texto de entrada y:
Si también ha muestreado textos codificados en UTF que no comienzan con ninguna lista de materiales, el segundo paso cubrirá los que se deslizaron desde el primer paso.
Hasta ahora, funciona para mí (los datos de muestra y los datos de entrada posteriores son subtítulos en varios idiomas) con tasas de error decrecientes.
fuente
La herramienta "uchardet" hace esto bien usando modelos de distribución de frecuencia de caracteres para cada juego de caracteres. Los archivos más grandes y más archivos "típicos" tienen más confianza (obviamente).
En ubuntu, tu solo
apt-get install uchardet
.En otros sistemas, obtenga la fuente, el uso y los documentos aquí: https://github.com/BYVoid/uchardet
fuente
brew install uchardet
El constructor de la clase StreamReader toma un parámetro 'detectar codificación'.
fuente
Si puede vincular a una biblioteca C, puede usar
libenca
. Ver http://cihar.com/software/enca/ . Desde la página del manual:Es GPL v2.
fuente
Tengo el mismo problema pero aún no encontré una buena solución para detectarlo automáticamente. Ahora estoy usando PsPad (www.pspad.com) para eso;) Funciona bien
fuente
Dado que básicamente se trata de heurística, puede ser útil usar la codificación de los archivos recibidos previamente de la misma fuente como primera sugerencia.
La mayoría de las personas (o aplicaciones) hacen cosas casi en el mismo orden cada vez, a menudo en la misma máquina, por lo que es muy probable que cuando Bob cree un archivo .csv y lo envíe a Mary, siempre usará Windows-1252 o cualquiera que sea el valor predeterminado de su máquina.
Siempre que sea posible, un poco de capacitación del cliente nunca está de más :-)
fuente
En realidad estaba buscando una forma genérica, no de programación, de detectar la codificación del archivo, pero aún no la encontré. Lo que encontré al probar con diferentes codificaciones fue que mi texto era UTF-7.
Entonces, donde estaba haciendo por primera vez: StreamReader file = File.OpenText (fullfilename);
Tuve que cambiarlo a: archivo StreamReader = nuevo StreamReader (fullfilename, System.Text.Encoding.UTF7);
OpenText supone que es UTF-8.
También puede crear el StreamReader como este nuevo StreamReader (fullfilename, true), el segundo parámetro significa que debería intentar detectar la codificación desde el byteordermark del archivo, pero eso no funcionó en mi caso.
fuente
Abra el archivo en AkelPad (o simplemente copie / pegue un texto ilegible), vaya a Editar -> Selección -> Recodificar ... -> marque "Detectar automáticamente".
fuente
Como complemento de la publicación ITmeze, he usado esta función para convertir la salida del puerto C # para Mozilla Universal Charset Detector
MSDN
fuente
Gracias @ Erik Aronesty por mencionarlo
uchardet
.Mientras tanto existe la (misma?) Herramienta para Linux:
chardet
.O, en cygwin, puede usar:
chardetect
.Consulte: página de manual de chardet: https://www.commandlinux.com/man-page/man1/chardetect.1.html
Esto detectará heurísticamente (adivinará) la codificación de caracteres para cada archivo dado e informará el nombre y el nivel de confianza para la codificación de caracteres detectada de cada archivo.
fuente
Uso este código para detectar la página de códigos ansi predeterminada de Unicode y Windows cuando leo un archivo. Para otras codificaciones, es necesario verificar el contenido, manualmente o mediante programación. Esto se puede usar para guardar el texto con la misma codificación que cuando se abrió. (Yo uso VB.NET)
fuente
10Y (!) Había pasado desde que se le preguntó esto, y todavía no veo ninguna mención de la buena solución de MS, no GPL: la API IMultiLanguage2 .
La mayoría de las bibliotecas ya mencionadas se basan en UDE de Mozilla, y parece razonable que los navegadores ya hayan abordado problemas similares. No sé cuál es la solución de Chrome, pero desde que IE 5.0 MS ha lanzado la suya, es:
Es una llamada COM nativa, pero aquí hay un trabajo muy bueno de Carsten Zeumer, que maneja el desorden de interoperabilidad para el uso de .net. Hay algunos otros alrededor, pero en general esta biblioteca no recibe la atención que merece.
fuente