Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: Конвертация текста из WIN в UTF8 средствами perl  (Прочитано 4420 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн mastak777

  • Автор темы
  • Любитель
  • *
  • Сообщений: 98
    • Просмотр профиля
Раньше программировал в Винде, тексты (скрипты, формы и т.п.) были в основном в кодировке WIN. Сейчас перешел на Ubuntu и по ряду причин удобнее поменять кодировку на UTF.  
Написал модулек, который переконвертирует все папки в UTF.
Но есть такой нуансик. В одном файле могут встречаться строчки с разной кодировкой - WIN, KOI8, ENG. WIN нормально конвертируется в UTF8, а вот KOI8 что-то не очень. Вместо русского текста получается нечитаемый русский, к примеру, вместо "Сайту" (типа, "Сайту 5 лет") получается
яЮИРС
Строка кода:
my $ch = Lingua::DetectCharset::Detect($str); # определяем кодировку - KOI8
$str = Convert::Cyrillic::cstocs('koi8', 'UTF8', $str); # Конвертируем
Перепробовал несколько методов - результат один и тот же. Благо что не много таких строчек. Они (по-видимому) получаются в результате того, что файлы на сервере правятся не одним человеком. В кодировке Винды никаких различий не замечалось, а сейчас могут полезть глюки.
После перекодировки получаем (проверяем по строкам в каком-нибудь файле):
ENG остается ENG (эти строки я пропускаю)
WIN становится UTF8 (и нормально читаются)
KOI8 становится ENG (и не читаются, а должны бы тоже стать UTF8. Почему?)
Кто-нибудь сталкивался с такой проблемкой?
« Последнее редактирование: 22 Июля 2011, 09:53:36 от mastak777 »

Оффлайн RazrFalcon

  • O_o
  • Старожил
  • *
  • Сообщений: 3129
  • Zombie Mod
    • Просмотр профиля
    • Я на GitHub
1) не вин, а cp1251
2) iconv
Gentoo + KDE, Official Windows Hater
Хотите помочь нашей вики: https://help.ubuntu.ru/wiki/fixme

Оффлайн mastak777

  • Автор темы
  • Любитель
  • *
  • Сообщений: 98
    • Просмотр профиля
1) не вин, а cp1251
2) iconv
iconv - это консольная команда, а я же говорю о модулях perl. Не с консоли же я буду перекодировать файлы, заброшу модуль на сервер и перекодирую все прямо там. Ну и у себя тем же способом.
Впрочем, если б вы поподробнее писали, может было понятнее.
С консоли, кстати, тоже пытался - результат тот же.
И так
iconv -f win -t utf8 live.txt
И так
iconv -f koi8 -t utf8 live.txt
В строке, с кодировкой KOI8 - нечитаемая латиница. Остальные строки перекодируются нормально.
« Последнее редактирование: 22 Июля 2011, 12:33:22 от mastak777 »

Оффлайн wl

  • Старожил
  • *
  • Сообщений: 1393
    • Просмотр профиля
После перекодировки получаем (проверяем по строкам в каком-нибудь файле):
ENG остается ENG (эти строки я пропускаю)
WIN становится UTF8 (и нормально читаются)
KOI8 становится ENG (и не читаются, а должны бы тоже стать UTF8. Почему?)
Кто-нибудь сталкивался с такой проблемкой?

Бывало нечто похожее.
Все зависит от версии перла и от того, как читаются строки из файла.
Полагаю, у вас >= 5.6

По умолчанию кодировкой всего прочитанного считается utf-8, там специальный флаг стоит.
Это читали?

Да, а утилита iconv используется неправильно, правильная кодировка у нее называется не win, а cp1251
« Последнее редактирование: 22 Июля 2011, 13:21:43 от wl »
На свете феньки есть такие, брат Горацио, которых лохи просто не секут. (Шекспир, "Гамлет", вольный перевод)

Оффлайн mastak777

  • Автор темы
  • Любитель
  • *
  • Сообщений: 98
    • Просмотр профиля
Разобрался. Спасибо. Здесь промелькнул пост (не запомнил чей), который и помог разобраться.
Дело в том, что
my $ch = Lingua::DetectCharset::Detect($str);
выдает довольно скудную инфу о кодировке - WIN, KOI8, UTF8, ENG.
В частности под KOI8 может находиться довольно широкий диапазон кодировок. их можно посмотреть
$ iconv -l
Тогда с консоли подобрал нужную кодировку, в данном случае KOI8 = cp1251
$ perl -pe 'BEGIN { binmode(STDIN,":encoding(cp1251)"); binmode(STDOUT, ":encoding(utf8)"); } '  < live.txt
А могло быть что-нибудь другое. Я полагал, что KOI8 это и есть KOI8.
В итоге получилось так.
        my $ch = Lingua::DetectCharset::Detect($str);
if($ch eq 'WIN'){
      $str = Convert::Cyrillic::cstocs('WIN', 'UTF8', $str);
}elsif($ch eq 'KOI8'){
$converter = Text::Iconv->new("cp1251", "utf-8");
       $str = $converter->convert($str);
}
В общем запутано немного, сам не все понял, но проблема решена.
Спасибо за подсказку.
« Последнее редактирование: 22 Июля 2011, 13:24:53 от mastak777 »

Оффлайн wl

  • Старожил
  • *
  • Сообщений: 1393
    • Просмотр профиля
данном случае KOI8 = cp1251
Вот это круто!  :2funny:

Если у вас кодировка определилась как koi-8, но на самом деле это cp-1251, значит, она определилась неправильно.
На свете феньки есть такие, брат Горацио, которых лохи просто не секут. (Шекспир, "Гамлет", вольный перевод)

Оффлайн mastak777

  • Автор темы
  • Любитель
  • *
  • Сообщений: 98
    • Просмотр профиля
Если у вас кодировка определилась как koi-8, но на самом деле это cp-1251, значит, она определилась неправильно.
Хм. Она, оказывается неправильно определилась! Ну надо же.. Вот ведь, стали модули делать, даже кодировку определить не могут.
Ясно одно. То, что выдает детектер
my $ch = Lingua::DetectCharset::Detect($str);
не является кодировкой в прямом смысле.
Мне этой инфы достаточно, чтобы продолжить работу. Вникать в нюансы и тонкости нет времени и желания.

Оффлайн wl

  • Старожил
  • *
  • Сообщений: 1393
    • Просмотр профиля
Если в алгоритме используется частотный анализ, а текст короткий, то ничего удивительного.
На свете феньки есть такие, брат Горацио, которых лохи просто не секут. (Шекспир, "Гамлет", вольный перевод)

Оффлайн mastak777

  • Автор темы
  • Любитель
  • *
  • Сообщений: 98
    • Просмотр профиля
Если в алгоритме используется частотный анализ, а текст короткий, то ничего удивительного.
Ну, да. Вот такая конструкция не распознается.
my $str='$main::H{NAME}=~s/[^\w\.À-ßà-ÿ ]//g;';
my $ch = Lingua::DetectCharset::Detect($str);
Выдает ENG , типа нет кириллицы. А отдельными символами вообще труба.

 

Страница сгенерирована за 0.023 секунд. Запросов: 21.