W naszej aplikacji otrzymujemy pliki tekstowe ( .txt
, .csv
etc.) z różnych źródeł. Podczas czytania pliki te czasami zawierają śmieci, ponieważ pliki zostały utworzone na innej / nieznanej stronie kodowej.
Czy istnieje sposób (automatycznego) wykrycia strony kodowej pliku tekstowego?
detectEncodingFromByteOrderMarks
Na StreamReader
konstruktora, pracuje UTF8
i inne pliki Unicode oznakowane, ale szukam sposobu na wykrycie stron kodowych, jak ibm850
, windows1252
.
Dzięki za odpowiedzi, właśnie to zrobiłem.
Pliki, które otrzymujemy, pochodzą od użytkowników końcowych, nie mają pojęcia o stronach kodowych. Odbiorniki są również użytkownikami końcowymi, do tej pory wiedzą o stronach kodowych: Strony kodowe istnieją i są denerwujące.
Rozwiązanie:
- Otwórz otrzymany plik w Notatniku, spójrz na zniekształcony fragment tekstu. Jeśli ktoś nazywa się François lub coś w tym rodzaju, dzięki swojej ludzkiej inteligencji możesz to odgadnąć.
- Utworzyłem małą aplikację, za pomocą której użytkownik może otworzyć plik, i wprowadzić tekst, o którym wie, że pojawi się on w pliku, gdy zostanie użyta poprawna strona kodowa.
- Zapętlaj wszystkie strony kodowe i wyświetlaj te, które dają rozwiązanie z tekstem dostarczonym przez użytkownika.
- Jeśli pojawi się więcej niż jedna strona kodowa, poproś użytkownika o podanie większej ilości tekstu.
Jeśli chcesz wykryć kodowanie inne niż UTF (tj. Brak BOM), zasadniczo sprowadzasz się do heurystyki i analizy statystycznej tekstu. Możesz przyjrzeć się artykułowi Mozilli na temat uniwersalnego wykrywania zestawów znaków (ten sam link, z lepszym formatowaniem za pomocą Wayback Machine ).
źródło
Czy próbowałeś portu C # dla Mozilla Universal Charset Detector
Przykład z http://code.google.com/p/ude/
źródło
private Encoding GetEncodingFromString(string encoding) { try { return Encoding.GetEncoding(encoding); } catch { return Encoding.ASCII; } }
To jest oczywiście nieprawda. Każda przeglądarka internetowa ma jakiś uniwersalny wykrywacz zestawów znaków, który radzi sobie ze stronami, które nie mają żadnego oznaczenia kodowania. Firefox ma jeden. Możesz pobrać kod i zobaczyć, jak to robi. Zobacz trochę dokumentacji tutaj . Zasadniczo jest to heurystyka, ale działa naprawdę dobrze.
Biorąc pod uwagę rozsądną ilość tekstu, można nawet wykryć język.
Oto kolejny, który właśnie znalazłem za pomocą Google:
źródło
a character encoding declaration is required even if the encoding is US-ASCII
- brak deklaracji powoduje użycie algorytmu heurystycznego, a nie powrót do UTF8.Wiem, że jest już za późno na to pytanie i to rozwiązanie nie spodoba się niektórym (ze względu na jego ukierunkowanie na język angielski i brak testów statystycznych / empirycznych), ale działało bardzo dobrze dla mnie, szczególnie w przypadku przetwarzania przesłanych danych CSV:
http://www.architectshack.com/TextFileEncodingDetector.ashx
Zalety:
Uwaga: to ja napisałem tę klasę, więc oczywiście weź to z odrobiną soli! :)
źródło
Notepad ++ ma tę funkcję od razu po wyjęciu z pudełka. Obsługuje również zmianę.
źródło
Szukając innego rozwiązania, znalazłem to
https://code.google.com/p/ude/
to rozwiązanie jest dość ciężkie.
Potrzebowałem podstawowej detekcji kodowania, opartej na 4 pierwszych bajtach i prawdopodobnie wykrywaniu zestawu znaków xml - więc wziąłem przykładowy kod źródłowy z Internetu i dodałem nieco zmodyfikowaną wersję
http://lists.w3.org/Archives/Public/www-validator/2002Aug/0084.html
napisane dla Java.
Wystarczy odczytać prawdopodobnie pierwsze 1024 bajty z pliku, ale ładuję cały plik.
źródło
Jeśli ktoś szuka rozwiązania 93,9%. To działa dla mnie:
źródło
Zrobiłem coś podobnego w Pythonie. Zasadniczo potrzebujesz wielu przykładowych danych z różnych kodowań, które są rozkładane przez przesuwne dwubajtowe okno i przechowywane w słowniku (hash), kluczowanym na parach bajtów zapewniających wartości list kodowania.
Biorąc pod uwagę ten słownik (skrót), bierzesz tekst wejściowy i:
Jeśli próbkowałeś również teksty zakodowane w UTF, które nie zaczynają się od żadnej BOM, drugi krok obejmie te, które wymknęły się z pierwszego kroku.
Jak dotąd działa dla mnie (dane przykładowe i kolejne dane wejściowe są napisami w różnych językach) ze zmniejszającymi się wskaźnikami błędów.
źródło
Narzędzie „uchardet” robi to dobrze, wykorzystując modele dystrybucji częstotliwości znaków dla każdego zestawu znaków. Większe pliki i bardziej „typowe” pliki mają większą pewność (oczywiście).
Na Ubuntu, po prostu
apt-get install uchardet
.W innych systemach pobierz źródło, użycie i dokumenty tutaj: https://github.com/BYVoid/uchardet
źródło
brew install uchardet
Konstruktor klasy StreamReader przyjmuje parametr „wykryj kodowanie”.
źródło
Jeśli możesz połączyć się z biblioteką C, możesz użyć
libenca
. Zobacz http://cihar.com/software/enca/ . Ze strony podręcznika:To GPL v2.
źródło
Masz ten sam problem, ale nie znalazłem jeszcze dobrego rozwiązania do jego automatycznego wykrycia. Teraz używam do tego PsPad (www.pspad.com);) Działa dobrze
źródło
Ponieważ zasadniczo sprowadza się to do heurystyki, pomocne może być użycie kodowania wcześniej odebranych plików z tego samego źródła jako pierwszej wskazówki.
Większość ludzi (lub aplikacji) za każdym razem robi rzeczy w tej samej kolejności, często na tej samej maszynie, więc jest całkiem prawdopodobne, że kiedy Bob utworzy plik .csv i wyśle go do Mary, zawsze będzie korzystał z Windows-1252 lub cokolwiek domyślnie ma jego maszyna.
Tam gdzie to możliwe, odrobina szkoleń dla klientów nigdy nie boli :-)
źródło
Tak naprawdę szukałem ogólnego, nie programistycznego sposobu wykrywania kodowania plików, ale jeszcze go nie znalazłem. Testując przy użyciu różnych kodowań, znalazłem, że mój tekst to UTF-7.
Więc gdzie po raz pierwszy robiłem: StreamReader file = File.OpenText (pełna nazwa pliku);
Musiałem to zmienić na: Plik StreamReader = nowy StreamReader (pełna nazwa pliku, System.Text.Encoding.UTF7);
OpenText zakłada, że jest to UTF-8.
możesz również utworzyć StreamReader, jak ten nowy StreamReader (pełna nazwa pliku, prawda), drugi parametr oznaczający, że powinien spróbować wykryć kodowanie z bajtuordermark pliku, ale to nie zadziałało w moim przypadku.
źródło
Otwórz plik w AkelPad (lub po prostu skopiuj / wklej zniekształcony tekst), przejdź do Edycja -> Wybór -> Przekoduj ... -> zaznacz „Autodetekcja”.
źródło
Jako dodatek do postu ITmeze, użyłem tej funkcji do konwersji wyjścia portu C # dla Mozilla Universal Charset Detector
MSDN
źródło
Dzięki @ Erik Aronesty za wzmiankę
uchardet
.Tymczasem istnieje (to samo?) Narzędzie dla systemu Linux:
chardet
.Albo na Cygwin możesz użyć:
chardetect
.Zobacz: strona man chardet: https://www.commandlinux.com/man-page/man1/chardetect.1.html
To heurystycznie wykryje (zgadnie) kodowanie znaków dla każdego podanego pliku i zgłosi nazwę i poziom pewności dla wykrytego kodowania znaków dla każdego pliku.
źródło
Używam tego kodu do wykrywania domyślnej strony kodowej ansi Windows i Unicode podczas czytania pliku. W przypadku innych kodowań konieczna jest kontrola treści, ręcznie lub przez programowanie. Można to wykorzystać do zapisania tekstu z takim samym kodowaniem, jak w momencie jego otwarcia. (Używam VB.NET)
źródło
Minęło 10 lat (!), Odkąd o to zapytano, a mimo to nie widzę wzmianki o dobrym, nie- GPL'owym rozwiązaniu MS : IMultiLanguage2 API.
Większość bibliotek już wspomnianych opiera się na UDE Mozilli - i wydaje się rozsądne, że przeglądarki już rozwiązały podobne problemy. Nie wiem, jakie jest rozwiązanie chrome, ale od czasu wydania IE 5.0 MS, i jest to:
Jest to natywne wywołanie COM, ale oto bardzo fajna praca Carstena Zeumera, która obsługuje bałagan interop dla użycia .net. Istnieje kilka innych, ale ogólnie rzecz biorąc, ta biblioteka nie przyciąga uwagi, na jaką zasługuje.
źródło