У меня есть набор файлов SHST_JIS (японского) csv из Windows, который я пытаюсь обработать на Linux-сервере под управлением Perl v5.10.1 с использованием регулярных выражений для замены строк.Обработка файлов Perl на SHIFT_JIS закодированных японских файлах
Это мое требование: Я хочу, чтобы регулярные выражения скрипта Perl были понятными для человека (по крайней мере, для японского человека) Т.е. например: s/北/0/g; Вместо него усеяны шестым кодом s/\ x {4eba}/0/g;
Сейчас я редактирую скрипт Perl в Notepad ++ в Windows и вставляя строку, которую мне нужно найти из файла данных csv на скрипт Perl.
У меня есть следующий рабочий сценарий тестирования ниже:
use strict;
use warnings;
use utf8;
open (IN1, "<:encoding(shift_jis)", "${work_dir}/tmp00.csv") or die "Error: tmp00.csv\n";
open (OUT1, "+>:encoding(shift_jis)" , "${work_dir}/tmp01.csv") or die "Error: tmp01.csv\n";
while (<IN1>)
{
print $_ . "\n";
chomp;
s/北/0/g;
s/10:00/9:00/g;
print OUT1 "$_\n";
}
close IN1;
close OUT1;
Это успешно заменить 10:00 с 9:00 в .csv файл, но вопрос я не смог заменить 北 (то есть. North) с 0, если не использовать utf8 также в верхней части.
Вопросы:
1) В открытой документации, http://perldoc.perl.org/functions/open.html, я не видел использовать utf8 как требование, если оно не подразумевается?
a) Если бы я использовал utf8 только, то первый оператор печати в цикле печатает символ мусора на моем экране xterm.
b) Если бы я открывал только с: encoding (shift_jis), то первый оператор печати в цикле печатал японский символ на моем экране xterm, но замены не было бы. Существует никаких предупреждений о том, что использование utf8 не указано.
c) Если я использовал оба a) и b), то этот пример работает.
Как «использовать utf8» изменить поведение вызова open с помощью: enoding (shift_jis) в этом скрипте Perl?
2) Я также попытался открыть файл без какой-либо кодировки, не будет ли Perl обрабатывать строки файла как необработанные байты и иметь возможность выполнять регулярное выражение таким образом, если строки, вставленные в скрипт, являются в той же кодировке, что и текст в исходном файле данных? Ранее я смог выполнить замену имени файла без указания какой-либо кодировки (см. Мой связанный пост здесь: Perl Japanese to English filename replacement).
Спасибо.
ОБНОВЛЕНИЕ 1
Тестирования простой локализации образец в Perl для имени файла и файл замены текста на японском языке
В Windows XP, скопируйте 南 символ из файла в формате CSV данных и скопируйте в буфер обмена, затем используйте его как имя файла (то есть. 南 .txt), так и содержимое файла (南). В Notepad ++ чтение файла под кодировкой UTF-8 показывает x93xEC, его чтение под SHIFT_JIS отображает 南.
Сценарий:
Используйте следующий Perl south.pl скрипт, который будет выполняться на сервере Linux с Perl 5,10
#!/usr/bin/perl
use feature qw(say);
use strict;
use warnings;
use utf8;
use Encode qw(decode encode);
my $user_dir="/usr/frank";
my $work_dir = "${user_dir}/test_south";
# forward declare the function prototypes
sub fileProcess;
opendir(DIR, ${work_dir}) or die "Cannot open directory " . ${work_dir};
# readdir OPTION 1 - shift_jis
#my @files = map { Encode::decode("shift_jis", $_); } readdir DIR; # Note filename could not be decoded as shift_jis
#binmode(STDOUT,":encoding(shift_jis)");
# readdir OPTION 2 - utf8
my @files = map { Encode::decode("utf8", $_); } readdir DIR; # Note filename could be decoded as utf8
binmode(STDOUT,":encoding(utf8)"); # setting display to output utf8
say @files;
# pass an array reference of files that will be modified
fileNameTranslate();
fileProcess();
closedir(DIR);
exit;
sub fileNameTranslate
{
foreach (@files)
{
my $original_file = $_;
#print "original_file: " . "$original_file" . "\n";
s/南/south/;
my $new_file = $_;
# print "new_file: " . "$_" . "\n";
if ($new_file ne $original_file)
{
print "Rename " . $original_file . " to \n\t" . $new_file . "\n";
rename("${work_dir}/${original_file}", "${work_dir}/${new_file}") or print "Warning: rename failed because: $!\n";
}
}
}
sub fileProcess
{
# file process OPTION 3, open file as shift_jis, the search and replace would work
# open (IN1, "<:encoding(shift_jis)", "${work_dir}/south.txt") or die "Error: south.txt\n";
# open (OUT1, "+>:encoding(shift_jis)" , "${work_dir}/south1.txt") or die "Error: south1.txt\n";
# file process OPTION 4, open file as utf8, the search and replace would not work
open (IN1, "<:encoding(utf8)", "${work_dir}/south.txt") or die "Error: south.txt\n";
open (OUT1, "+>:encoding(utf8)" , "${work_dir}/south1.txt") or die "Error: south1.txt\n";
while (<IN1>)
{
print $_ . "\n";
chomp;
s/南/south/g;
print OUT1 "$_\n";
}
close IN1;
close OUT1;
}
Результат:
(BAD) Uncomment Варианты 1 и 3, (Комментарий Вариант 2 и 4) Настройка: кодировка Readdir, SHIFT_JIS; файл открыт кодирование SHIFT_JIS Результат: файл замена имя не удалось .. Ошибка: utf8 "\ x93" не отображает в Unicode в .//south.pl линии 68. \ x93
(БАД) Раскоментируйте Вариант 2 и 4 (Комментарий Вариант 1 и 3) Настройка: кодировка Readdir, utf8; file open encoding utf8 Результат: смена имени файла сработала, сгенерирован файл south.txt Но сбой в замене содержимого файла south1.txt, он имеет содержимое \ x93(). Ошибка: "\ х {FFFD}" не отображает в shiftjis на .//south.pl линии 25. ... -ao = (Bx {FFFD} .txt
(ХОРОШО) Раскоментируйте Вариант 2 и 3, (Комментарий Вариант 1 и 4) Настройка: кодировка Readdir, utf8; открытая кодировка файла SHIFT_JIS Результат: смена имени файла сработала, сгенерирован сгенерированный south.txt Работа с содержимым файла содержимого South1.txt, содержание юга на нем.
Вывод:
мне пришлось использовать другую схему кодирования для этого примера, чтобы работать р roperly. Readdir utf8 и обработки файлов SHIFT_JIS, поскольку содержимое файла csv кодировалось SHIFT_JIS.
Спасибо Дэйв, вы могли бы объяснить разницу между UTF-8 и SHIFT_JIS? UTF8 - это схема кодирования, поэтому моя путаница в том, что если SHIFT_JIS также является (другой) схемой кодирования, тогда, когда я использую прагму utf8, тогда мой исходный скрипт (который содержит SHIFT_JIS) не будет интерпретироваться как один байт, но как utf8 символов. Затем я вызываю open с: encoding (SHIFT_JIS), символы из файла будут символами SHIFT_JIS. Если две схемы кодирования не равны, я не вижу, как это будет работать. Я не мог сказать, так ли это на странице wikiipedia SHIFT_JIS. – frank
Я обновил пример, который иллюстрирует другую схему кодирования, которую я использовал, чтобы заменить замену имени файла и замены файла. – frank
Кодирование имен файлов определяется операционной системой. Вы не можете это изменить. Кодирование содержимого файла определяется человеком, который пишет файл. –