Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
数据和ARGV文件句柄上的Perl UTF-8编码_Perl_Unicode_Utf 8 - Fatal编程技术网

数据和ARGV文件句柄上的Perl UTF-8编码

数据和ARGV文件句柄上的Perl UTF-8编码,perl,unicode,utf-8,Perl,Unicode,Utf 8,我有一些包含大量Unicode希伯来语和希腊语的文本文件,它们需要包含在HTML…元素中。这些文件属于已运行多年的项目 大约八年前,我们成功地使用这个Perl脚本来完成这项工作 #/usr/bin/perl 使用utf8; 我的$table=[ { FROM=>“\\x{0590}”, TO=>“\\x{05ff}”, REGEX=>“[\\x{0590}-\\x{05ff}]”, 打开=>“”, 关闭=>“”, }, { FROM=>“\\x{0370}”, TO=>“\\x{03E1}”,

我有一些包含大量Unicode希伯来语和希腊语的文本文件,它们需要包含在HTML
元素中。这些文件属于已运行多年的项目

大约八年前,我们成功地使用这个Perl脚本来完成这项工作

#/usr/bin/perl
使用utf8;
我的$table=[
{
FROM=>“\\x{0590}”,
TO=>“\\x{05ff}”,
REGEX=>“[\\x{0590}-\\x{05ff}]”,
打开=>“”,
关闭=>“”,
},
{
FROM=>“\\x{0370}”,
TO=>“\\x{03E1}”,
REGEX=>“[\\x{0370}-\\x{03E1}].[\\x{1F00}-\\x{1FFF}]”,
打开=>“”,
关闭=>“”,
},
];
binmode(标准输入“:utf8”);
binmode(标准输入,“编码(utf8)”);
binmode(标准输出,“:utf8”);
二进制模式(标准输出,“编码(utf8)”;
而(){
我的$line=$\ux;
foreach my$l(@$表){
my$regex=$l->{regex},
my($from,$to)=($l->{from},$l->{to});
my($open,$close)=($l->{open},$l->{close});
$line=~s/($regex)+(\s+($regex)+*)/$open\1$close/g;
}
打印$行;
}
它扫描文本文件以查找定义的Unicode范围,并插入相应的
span
包装器

我已经有一段时间没有使用这个脚本了,现在我需要处理更多的文本文件。但不知何故,Unicode并没有得到保留:Unicode文本正在被破坏,而不是被包装在
标记中

在我继续之前,我需要一个修复的帮助

下面是一些示例输入

Mary had a little כֶּבֶשׂ, its fleece was white as χιών. And πάντα that Mary went, the כֶּבֶשׂ was sure to go.
以下是我得到的输出:

Mary had a little ×Ö¼Ö¶×ֶש×, its fleece was white as ÏιÏν. And ÏάνÏα that Mary went, the ×Ö¼Ö¶×Ö¶×©× was sure to go.
就在此刻,我在一台装有LinuxMint13LTS的机器上。我的另一个操作系统是Ubuntu 14.04。Perl版本报告为v。5.14.2. 我是这样运行脚本的

perl uconv.pl infile.txt > outfile.txt

我不确定发生了什么,尽管看了不少堆栈溢出问题和答案(例如),但我一点也不知道。也许我需要设置一些环境变量?还是该脚本中的某些内容现在已被弃用?或者…?

您的输出很好。Perl正在为UTF-8编码的字符串打印正确的字节序列

例如,第一个希伯来语单词
包含这七个unicode字符

05DB   05BC   05B6   05D1   05B6   05E9   05C2
kaf    dagesh segol  bet    segol  shin   sin dot
D7 9B D6 BC D6 B6 D7 91 D6 B6 D7 A9 D7 82
以UTF-8编码为十四个字节(每个字符两个)

这就是您显示的格式错误字符串的内容

问题不在于程序打印了错误的字符,而在于您用来检查输出的任何东西都不需要UTF-8


更新

问题似乎出在
ARGV
,而不是
STDIN
。从空文件句柄读取实际上是从
ARGV
读取,因此在
STDIN
上使用
binmode
设置UTF-8 Perl IO层没有效果。此外,您不能以相同的方式设置
ARGV
的模式,因为它尚未打开

但是你可以通过使用

使用openqw/:std:encoding(utf8)/;
它指定要应用于新打开的输入(和输出)句柄的默认层,包括
ARGV
。因此,当第一次执行
时自动打开时,应正确读取数据


更新

我也刚刚明白为什么输出文本是错误的

我的错误想法是,即使将输入读取为八位字节序列而不是UTF-8编码的宽字符,但如果将这些八位字节复制到输出,而不进行修改,则仍应产生正确的结果

现在显而易见的是,虽然输入是以字节为单位的,
STDOUT
被设置为UTF-8编码,因此已经编码的数据将被重新编码。让我们把这个希伯来语单词从上面理解为lamb

[D7 9B] [D6 BC] [D6 B6] [D7 91] [D6 B6] [D7 A9] [D7 82]
由于
ARGV
仍设置为
:raw
,因此输入被解释为这十四个单字节字符,而不是七个UTF-8编码的宽字符

05DB   05BC   05B6   05D1   05B6   05E9   05C2
kaf    dagesh segol  bet    segol  shin   sin dot
D7 9B D6 BC D6 B6 D7 91 D6 B6 D7 A9 D7 82
现在,如果该字符串被打印出来,那么它将被编码到UTF-8中,因为这就是
STDOUT
的设置方式。ASCII(七位)字符将在UTF-8编码中保持不变,但此字符串中的所有“字符”都位于代码点0x80或更高,因此它们将被编码为多字节字符

对这十四个“字符”进行编码的结果是这一系列的二十八个八位字节

[C3 97] [C2 9B] [C3 96] [C2 BC] [C3 96] [C2 B6] [C3 97] [C2 91] [C3 96] [C2 B6] [C3 97] [C2 A9] [C3 97] [C2 82]
当显示为UTF8编码字符串时,将显示为十四个无意义的“字符”,这些字符是在不解码的情况下从
ARGV
读取的结果


呃,我认为QED。

[\x{0590}-\x{05ff}]
写得更好
\p{InHebrew}
。同样地
[\x{0370}-\x{03E1}]
。与希腊字符最接近的属性是
\p{InGreek}
,它包括科普特字符并扩展到U+03FF。@Borodin是否有一个特定的资源,您可以建议为这些unicode范围查找适当的字符类?@Miller:如果您只是搜索,说
U+263A
,那么第一个选项将是
FileFormat.info
上的相关页面,该页面充满了有用的内容。还有,它有一些非常有用的工具,但部分是德语,所以你可能想在Chrome上使用谷歌的翻译工具。当然,还有一个列表列出了Perl期望的名称。您可以测试属性与
0。。0xFFFF
循环。@Davïd:我希望你对我对你问题的修正感到满意。我的意图是,我的表述将帮助那些寻找相同解决方案的人找到它,而那些有类似问题的人如果内容不相关,则更有可能忽略它。@Borodin-这一切都很好。非常感谢!你让网络变得更好了。:)这当然是一个帮助-尽管我仍然感到困惑,因为我使用的任何文本编辑器(以UTF-8作为编码)都不表示Unicode字符。。。也没有添加
标记。有什么想法吗?标签很好用