您可能知道,在perl语言中,"utf8“意味着Perl对UTF-8的更宽松的理解,它允许使用在UTF-8中技术上不是有效代码点的字符。相反," UTF-8“(或"utf-8")是Perl对UTF-8更严格的理解,它不允许无效的代码点。
我有几个与此区别相关的用法问题:
默认情况下,
open
和像'>:utf8‘这样的层和像’>:open
(Utf8)‘这样的层有什么区别?这两种方法都可以用于'utf8‘和’UTF-8‘吗?发布于 2018-03-01 07:07:30
╔════════════════════════════════════════════╤══════════════════════╗
║ │ ║
║ On Read │ On Write ║
║ │ ║
Perl ╟─────────────────────┬──────────────────────┼──────────────────────╢
5.26 ║ │ │ ║
║ Invalid encoding │ Outside of Unicode, │ Outside of Unicode, ║
║ other than sequence │ Unicode nonchar, or │ Unicode nonchar, or ║
║ length │ Unicode surrogate │ Unicode surrogate ║
║ │ │ ║
╔══════════════════╬═════════════════════╪══════════════════════╪══════════════════════╣
║ ║ │ │ ║
║ :encoding(UTF-8) ║ Warns and Replaces │ Warns and Replaces │ Warns and Replaces ║
║ ║ │ │ ║
╟──────────────────╫─────────────────────┼──────────────────────┼──────────────────────╢
║ ║ │ │ ║
║ :encoding(utf8) ║ Warns and Replaces │ Accepts │ Warns and Outputs ║
║ ║ │ │ ║
╟──────────────────╫─────────────────────┼──────────────────────┼──────────────────────╢
║ ║ │ │ ║
║ :utf8 ║ Corrupt scalar │ Accepts │ Warns and Outputs ║
║ ║ │ │ ║
╚══════════════════╩═════════════════════╧══════════════════════╧══════════════════════╝
Click here if you have trouble viewing the above table
请注意,:encoding(UTF-8)
实际上使用utf8进行解码,然后检查结果字符是否在可接受的范围内。这减少了错误输入的错误消息的数量,所以它是好的。
(编码名称不区分大小写。)
用于生成上表的测试:
在读取时
:encoding(UTF-8)
$ printf "\xC3\xA9\n\xEF\xBF\xBF\n\xED\xA0\x80\n\xF8\x88\x80\x80\x80\n\x80\n“| perl -MB -nle‘use open ":std",":encoding(UTF-8)";my $sv = B::svref_2object(\$_);printf "%vX%s (内部:%vX,UTF8=%d)\n",$_,长度($_)==1?"“:”= $_",$sv->PVX,utf8::is_utf8($_);‘utf8 "\xFFFF“不映射到Unicode。utf8 "\xD800“不映射到Unicode。utf8 "\x200000“不映射到Unicode。utf8 "\x80“不映射到Unicode。E9 (内部: C3.A9,UTF8=1) 5C.78.7B.46.46.46.46.7D = \x{FFFF} (内部:5C.78.7B.46.46.46.7D,UTF8=1) 5C.78.7B.44.38.30.30.7D = \x{D800} (内部: 5C.78.7B.44.38.30.30.7D,UTF8=1) 5C.78.7B.32.30.30.30.30.30.7D = \x{200000} (内部: 5C.78.7B.32.30.30.30.30.30.7D,UTF8=1) 5C.78.38.30 = \x80 (内部: 5C.78.38.30,UTF8=1)
:encoding(utf8)
$ printf "\xC3\xA9\n\xEF\xBF\xBF\n\xED\xA0\x80\n\xF8\x88\x80\x80\x80\n\x80\n“| perl -MB -nle‘use open ":std",":encoding(utf8)";my $sv = B::svref_2object(\$_);printf "%vX%s (内部:%vX,UTF8=%d)\n",$_,长度($_)==1?"“:”= $_",$sv->PVX,utf8::is_utf8($_);‘utf8 "\x80“不映射到Unicode。E9 (内部: C3.A9,UTF8=1) FFFF (内部: EF.BF.BF,UTF8=1) D800 (内部:EF.BF.BF,UTF8=1) 200000 (内部: F8.88.80.80.80,UTF8=1) 5C.78.38.30 = \x80 (内部: 5C.78.38.30,ED.A0.30,ED.A0.80,ED.A0.80)5C.78.38.30=\x80(内部:5C.78.38.30,ED.A0.80,ED.A0.
$ printf "\xC3\xA9\n\xEF\xBF\xBF\n\xED\xA0\x80\n\xF8\x88\x80\x80\x80\n\x80\n“| perl -MB -nle‘use open ":std",":utf8";my $sv = B::svref_2object(\$_);printf "%vX%s (内部:%vX,UTF8=%d)\n",$_,length($_)==1?"“:”= $_",$sv->PVX,utf8::is_utf8($_);‘E9 (internal: C3.A9,UTF8=1) FFFF (internal: EF.BF.BF,UTF8=1) D800 (internal: ED.A0.80,UTF8=1) 200000 (internal: F8.88.80.80.80,UTF8=1) -e第4行,<>行5.0 (internal: 80,UTF8=1)中的UTF-8字符格式错误:\x80 (意外的继续字节0x80,没有前面的起始字节)
写入时
:encoding(UTF-8)
$ perl -e‘使用open ":std",“:编码(UTF-8)”;打印"\x{E9}\n";打印"\x{FFFF}\n";打印"\x{D800}\n";打印"\x{20_0000}\n";"\x{d800}“未映射到utf8。"\x{200000}“不映射到utf8。$ od -t c a 0000000 303 251 \n \x{F} \n \x{D 0000020 8 0 0} \n \x{2 0 0 0} \n 0000040 $ cat aé\x{FFFF} \x{D800} \x{200000}
:encoding(utf8)
$ perl -e‘use open ":std",":encoding(utf8)";打印"\x{E9}\n";打印"\x{FFFF}\n";打印"\x{D800}\n";打印"\x{20_0000}\n";Unicode代理项▒
:utf8
在UTF-8中的-e第4行是非法的.代码点0x200000不是Unicode,在打印时可能无法移植到-e第5行.$ od -t c a 0000000 303 251 \n 355 240 200 \n 370 210 200 200 \n 0000015 $ cat aé▒cat与:encoding(utf8)
.结果相同
使用Perl 5.26进行了测试。
默认情况下,
Encode::encode会将无效字符替换为替换字符。即使你传递更松散的"utf8“作为编码,这也是真的吗?
Perl字符串是32位或64位字符的字符串,具体取决于构建。utf8可以对任何72位整数进行编码。因此,它能够对它需要编码的所有字符进行编码。
https://stackoverflow.com/questions/49038533
复制相似问题