Почему Perl теряет иностранные символы в Windows;это можно исправить (если да, то как)? - PullRequest
5 голосов
/ 24 декабря 2010

Обратите внимание, как ã меняется на a. ПРИМЕЧАНИЕ 2: Прежде чем винить в этом CMD.EXE и странность канала Windows, ознакомьтесь с экспериментом 2 ниже, в котором аналогичная проблема возникает при использовании File :: Find.

Конкретная проблема, которую я пытаюсь решить, связана с работой с файлами изображений, хранящимися на локальном диске, и манипулированием именами файлов, которые могут содержать иностранные символы. Два эксперимента, показанные ниже, являются промежуточными этапами отладки.

Символ ã встречается в латинских языках. например http://pt.wikipedia.org/wiki/Cão

Эксперимент 1

Посмотрите внимательно, обратите внимание, как cão становится cao. alt text

Эксперимент 2

Здесь я попытался использовать File :: Find вместо конвейерного ввода, в случае, если проблема была в реализации Windows оператора |. На самом деле проблема усугубляется, так как ~a становится Pi: alt text


Отладочное обновление:

Я попробовал некоторые приемы, перечисленные в http://perldoc.perl.org/perlunicode.html, например use utf8, use feature 'unicode_strings' и т. Д. Безрезультатно.


Информация о среде и версии

Операционная система - Windows 7, 64-разрядная.

Perl:

This is perl 5, version 12, subversion 2 (v5.12.2) built for MSWin32-x64-multi-thread
(with 8 registered patches, see perl -V for more detail)

Copyright 1987-2010, Larry Wall

Binary build 1202 [293621] provided by ActiveState http://www.ActiveState.com
Built Sep  6 2010 22:53:42

Ответы [ 2 ]

6 голосов
/ 24 декабря 2010

Perl, как и многие другие языки сценариев, построен на среде выполнения C.

В Windows стандартная среда выполнения MS C для узких (байтовых) символов использует кодировку, которая по умолчанию соответствует системной кодировке Windows («Кодовая страница ANSI») для операций ввода-вывода, таких как открытие файлов или запись в консоль.

Кодовая страница ANSI всегда является кодировкой, специфичной для локали: обычно однобайтовая, но в некоторых локалях многобайтовая (например Китай, Япония и т. д.).Это никогда не UTF-8 или что-либо еще, способное воспроизвести весь Unicode;С какими символами Perl IO может справиться, зависит от языкового стандарта Windows (настройка «язык для программ, не поддерживающих Юникод»).

В то время как консольным приложениям можно дать UTF-8 с помощью команды chcp 65001, существуетряд серьезных несоответствий, которые возникают при этом.Это создает трудности для многих инструментов в Windows, и это то, что Microsoft действительно должна исправить, но до сих пор они считают, что Unicode равен UTF-16;все, кто хочет, чтобы Unicode работал, должны использовать интерфейсы widechar.

Таким образом, в настоящее время вы не сможете надежно работать с файлами, которые используют имена не-ASCII, в Perl в Windows.Извините.

Вы можете попробовать Python (который добавил специальную обработку имен только для Windows, чтобы обойти эту проблему в версии 2.3 и далее; см. PEP 277) или один из языков сценариев Windows с поддержкой Unicode.В любом случае, вывод Unicode на консоль в Windows по-прежнему сопряжен с большими трудностями.

1 голос
/ 24 декабря 2010

Следующие 3 лайнера работают, как и ожидалось, на моем недавно отчеканенном ActivePerl 5.12.2:

use utf8;
open($file, '>:encoding(UTF-8)', "output.txt") or die $!;
print $file "さっちゃん";

Я думаю, виновником является cmd.exe.

...