2012-03-27 24 views
8

Używam biblioteki iconv do interfejsu z nowoczesnego źródła wejściowego, które używa UTF-8 do starszego systemu, który używa Latin1, aka CP1252 (nadzbiór ISO-8859-1).Dlaczego iconv może konwertować wstępnie skomponowany formularz, ale nie rozłożyć formy "É" (z UTF-8 na CP1252)

Interfejs ostatnio nie przekonwertował francuskiego ciągu "Éducation", gdzie "É" zostało zakodowane jako hex 45 CC 81. Zauważ, że kodowanie miejsca docelowego ma znak "É", zakodowany jako C9.

Dlaczego iconv nie konwersji, że „e”? Sprawdziłem, czy narzędzie wiersza polecenia iconv dostępne w MacOS X 10.7.3 mówi, że nie może się skonwertować, i że moduł PERL iconv również się nie powiedzie.

Jest to tym bardziej zastanawiające, że przekształcona forma znaku "É" (zakodowana jako C3 89) konwertuje się dobrze.

Jest to błąd z iconv lub coś mnie ominęło?

Zauważ, że mam ten sam problem, jeśli próbuję konwertować z UTF-16 (gdzie "É" jest kodowane jako 00 C9 złożone lub 00 45 03 01 rozłożony).

Odpowiedz

5

Niestety iconv rzeczywiście nie radzić sobie z rozkładających się znaków w UTF-8, z wyjątkiem zainstalowanych w systemie Mac OS X. Wersja

Gdy mamy do czynienia z nazwami plików Mac, można użyć iconv z "utf8- mac "zestaw znaków". Uwzględnia ona również kilka modeli: idiosyncrasies of the Mac decomposed form.

Jednak wersje inne niż iconv lub libiconv nie obsługują tego, i nie mogłem znaleźć źródeł używanych na Macu, które zapewniają to wsparcie.

Zgadzam się z tobą, że iconv powinien być w stanie radzić sobie zarówno z formami NFC i NFD z UTF8, ale dopóki ktoś nie załatwi źródeł, musimy wykryć to ręcznie i poradzić sobie z nim przed przekazaniem rzeczy do iconv.

obliczu tego przykry problem, użyłem Perl Unicode :: Normalizuj modułu jako sugerowane przez Jukka.

#!/usr/bin/perl 

use Encode qw/decode_utf8 encode_utf8/; 
use Unicode::Normalize; 

while (<>) { 
    print encode_utf8(NFC(decode_utf8 $_)); 
} 
0

Użyj normalizer (w tym przypadku do Normalizacji Form C) przed wywołaniem iconv.

Program, który zajmuje się kodowaniem znaków (różne reprezentacje znaków lub, dokładniej, punkty kodowe, jako sekwencje bajtów) i konwersją między nimi, powinien traktować interpretację wstępną i formę złożoną jako odrębną. Rozłożony É składa się z dwóch punktów kodowych i jako taki różni się od prekompozycji É, która jest jednym punktem kodowym.

+1

Dzięki. To nie odpowiada na pytanie, dlaczego iconv odwzorowuje wstępnie skomponowany znak na kodowanie miejsca docelowego, ale nie na (z pewnością odrębną) rozłożoną postać. Dlaczego nie oba? Dlaczego nie ten drugi zamiast poprzedniego? W przypadku narzędzia/biblioteki konwersji jest to awaria, jeśli nie błąd. –

+0

@ Jean-Denis Muys, ponieważ wstępnie skomponowana forma to jeden znak Unicode, który jest reprezentowalny w docelowym kodowaniu zgodnie z tablicami odwzorowania, podczas gdy rozłożony formularz składa się z dwóch znaków Unicode, a drugi nie jest reprezentowany w Windows-1252 (CP1252) . Powiązanie pomiędzy tymi postaciami nie istnieje na poziomie kodowania znaków; jest to problem z wyższym poziomem protokołu (i jest to odpowiednik określonego rodzaju, a nie tożsamości). –

+1

Jesteś w rzeczywistości niepoprawny. Nie ma powodu, aby nie odwzorowywać rozłożonego znaku na jego odpowiednik CP-1252.Niezależnie od tego, czy "É" korzysta z jednej reprezentacji czy z drugiej, może i powinno być odwzorowane na znak CP-1252 "É". –