【发布时间】:2013-11-07 17:47:11
【问题描述】:
我正在修改一个 Perl 脚本,该脚本读取一系列 UCS-2LE 编码文件,其中包含制表符分隔格式的字符串,但是当字符串包含外部字符时,我无法在制表符上拆分字符串扩展拉丁字符集。
这是我从这些文件中读取的示例行(制表符分隔):
adını transcript asr turkish
当我让我的脚本将这些行写入输出文件以尝试调试此问题时,它正在编写以下内容:
ad1Ů1ĉtranscript asr turkish
它似乎无法识别土耳其字符后的制表符。这只发生在单词以非拉丁字符结尾(因此与制表符相邻)时。
这是代码块的一部分,其中发生写入输出文件并发生字符串拆分:
for my $infile (@ARGV){
if (!open (INFILE, "<$infile")){
die "Couldn't open $infile.\n";
}
binmode (OUTFILE, ":utf8");
while (<INFILE>) {
chomp;
$tTot++;
if ($lineNo == 1) {
$_ = decode('UCS-2LE', $_);
}
else {
$_ = decode('UCS-2', $_);
}
$_ =~ s/[\r\n]+//g;
my @foo = split('\t');
my $orth = $foo[0];
my $tscrpt = $foo[1];
my $langCode = $foo[3];
if (exists $codeHash{$langCode}) {
unless ($tscrpt eq '') {
check($orth, $tscrpt, $langCode);
}
}
else {
print OUTFILE "Unknown language code $langCode at line $lineNo.\n";
print OUTFILE $_; # printing the string that's not being split correctly
print OUTFILE "\n";
$tBad++;
}
}
此脚本的目的是检查输入文件中每一行的语言代码是否有效,并根据该代码,根据我们的转录系统检查每个单词的转录是否“合法” .
这是我迄今为止尝试过的:
- 在读入输入字符串时更改其编码 UTF-8、UTF-16 或 UTF-16LE
- 将 split() 字符更改为 '\w', /[[:blank:]]/、\p{Blank}、\x{09} 和 \N{U+0009}。
- 阅读 Perl Unicode 和 perlrebackslash 文档和任何其他远程 我可以在各个网站上找到的相关帖子
有人对我可能尝试的其他事情有任何建议吗?提前致谢!
我还应该提到,我无法控制输入文件编码和输出文件编码;我必须阅读 UCS-2LE 并输出 UTF-8。
【问题讨论】:
-
您应该能够在不到 5 行的时间内演示
split的问题。并且不要省略在更新中处理输出编码的行。另外,请提供您即将进行的演示失败的输入。od -t x1 file将以不会损坏的格式提供它。 -
顺便说一句,
$_ = decode('UCS-2LE', $_); s/^\x{FEFF}//;将是解码文件的更简单方法。更好的是在open中使用'<:raw:encoding(UCS-2le):crlf'而不是'<'。 -
您的
split到@foo似乎与您的输出几乎无关,除了触发一些错误消息。s语句下方的任何内容似乎都不会影响您打印(未编码的)$_。 -
顺便说一句,UCS-2le 是 UTF-16le 的子集。最好使用 UTF-16le 进行解码,以防您实际上是 UTF-16le。
-
@ikegami 感谢您的提示。我将尝试使用 UFT-16LE 打开文件。另外,因为我是新手,你能告诉我帖子的哪些部分没有用,以便下次我可以简洁而不遗漏重要部分吗?谢谢!