Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Помогите с перекодированием


Автор: infarch 1.6.2010, 10:33
К стыду своему должен признаться, что банальная с виду задача по перекодированию текста из utf8 в cp1251 поставила меня в тупик. Вроде все делаю "как книга пишет", а в ответ получаю или сообщения об ошибках, или Buchstabensalat.
Помогите пожалуйста! Дайте примитивный но рабочий пример для изучения!

Автор: arto 1.6.2010, 11:48
perl -plne 'BEGIN { use encoding "cp1251",STDOUT => "utf8" }'

Автор: infarch 1.6.2010, 13:12
Попытался это выполнить и получил ошибку: Can't find string terminator "'" anywhere before EOF at -e line 1.

Да и выглядит это немного неприменимо к моим целям. Я не хочу на лету перекодировать файлы. Мне нужно провести трансформацию отдельно взятой строки. Но даже если брать файлы... вот взгляните на пример:

Код

    open SRC, 'cp.txt' or die $!;
    open DEST, '>:utf8', 'dest.txt' or die $!;
    
    while (<SRC>){
        print DEST;
    }

    close SRC;
    close DEST;


У меня этот скрипт работает неправильно - в результате непонятные символы вместо utf. В чем может быть проблема?

Автор: arto 1.6.2010, 15:06
# print "как книга пишет" | iconv -f koi8-r -t cp1251 | perl -plne 'BEGIN { use encoding "cp1251",STDOUT => "utf8" }' | iconv -f utf8 -t koi8-r
как книга пишет
# 

# perl -e 'open F,"<:encoding(CP1251)",$ARGV[0]; open G,">:encoding(UTF-8)", $ARGV[1]; while (<F>) { print G; }' /tmp/test.txt /tmp/test.txt.utf
# cat /tmp/test.txt.utf | iconv -f utf8 -t koi8-r
как книга пишет
#

Автор: infarch 1.6.2010, 15:47
Возвращаясь к моему примеру: я подправил пару строк и добился перекодировки из cp1251 в utf8:

Код

    open SRC, '<:encoding(CP1251)', 'cp.txt' or die $!;
    open DEST, '>:encoding(UTF-8)', 'dest.txt' or die $!;


А вот как произвести обратную трансформацию? Я пробовал просто поменять енкодинги:

Код

    open SRC, '<:encoding(UTF-8)', 'utf.txt' or die $!;
    open DEST, '>:encoding(CP1251)', 'dest.txt' or die $!;


А в результате получил коллекцию ошибок типа: "\x{00d8}" does not map to cp1251 at...

Как можно провести такое преобразование?

Автор: arto 1.6.2010, 17:39
у меня работает.

# perl -e 'open F,"<:encoding(UTF-8)",$ARGV[0]; open G,">:encoding(KOI8-R)", $ARGV[1]; while (<F>) { print G; }' /tmp/test.txt /tmp/test.txt.koi
# cat /tmp/test.txt.koi
как книга пишет
#

Автор: infarch 1.6.2010, 18:03
Так тоже не работает. Аналогичная ошибка: "\x{00d8}" does not map to koi8-r at...
Может разница в среде выполнения? Я запускаю скрипт под виндой и использую Active Perl 5.8.8

Автор: arto 1.6.2010, 19:04
может быть. у меня линух

Автор: arto 1.6.2010, 20:12
попробовал на виндовс, нормально.
C:\>perl -v

This is perl, v5.10.0 built for MSWin32-x86-multi-thread
(with 9 registered patches, see perl -V for more detail)

Автор: infarch 2.6.2010, 10:41
Вы правы, работает. Это я лоханулся - в тестовом файле были датские символы. А для них таки нет соответствия в cp1251. Так что вопрос с файлами можно считать закрытым.

Но есть другой вопрос: как производить преобразование на уровне скаляров, без записи в файл?

Автор: arto 2.6.2010, 11:31
у меня сложилось впечатление, что вы категорически не желаете читать документацию.

Автор: infarch 2.6.2010, 12:12
Документация предоставляет много вариантов, так что я даже и не знаю какой метод предпочтительнее.

Автор: arto 2.6.2010, 14:55
perldoc Encode

# perl -MEncode=from_to -le '$a = "Документация предоставляет много вариантов"; from_to ($a,"koi8-r","utf8"); print $a' | iconv -f utf8 -t koi8-r
Документация предоставляет много вариантов
#

Автор: infarch 2.6.2010, 15:35
Спасибо за подсказку, посмотрю что оно такое. А то действительно не знал за что браться. Во первы есть utf8::* , потом например Unicode::String. И кто его знает за что браться...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)