之前有人会告诉我RTFM,我必须说 - 我已经挖通:
- 为什么现代的Perl避免默认UTF-8?
- 核对表用Perl去Unicode的方式
- 如何匹配字符串在Perl读音符号?
- 如何使“使用我的默认::”与现代的Perl和UTF8默认值?
- 和其他许多人(如perluniintro等) -但是- 当然 ,错过了什么
因此,基本的代码:
use 5.014; #getting 'unicode_strings' feature
use uni::perl; #turning on many utf8 things
use Unicode::Normalize qw(NFD NFC);
use warnings;
while(<>) {
chomp;
my $data = NFD($_);
say "OK" if utf8::is_utf8($data);
}
在这一点上, 从 UTF8编码STDIN我得到了一个正确的unicode字符串$data
,如“\ W”将与多字节[\p{Alphabetic}\p{Decimal_Number}\p{Letter_Number}]
也许更多的东西)。 这是确定和作品。
AFAIK $data
不包含UTF8,但在一个字符串perl's internal Unicode
格式。
现在的问题:
- 我怎么能保证(测试),任何
$other_data
包含有效的Unicode字符串? - 出于什么目的是UTF8 :: is_utf8($数据)? 整个UTF8附注是对我来说是一个谜。
据我所知, use utf8;
只是告诉Perl的,我的源代码是在UTF8的目的(这样做类似的事情时,我的脚本BOM标志开始的 - 为大尾端) - 从Perl的角度来看,我的源代码是这样一个外部文件 - 和Perl应该知道它是什么编码?
在上面的例子utf8::is_utf8($data)
将打印好的-但我不明白为什么。
内部Perl不使用UTF8,所以我的UTF8数据文件转换成Perl的内部Unicode的,那么,为什么utf8::is_utf8($data)
为返回true $data
,这是不是在UTF8格式? 或者是名不副实的,功能应该被命名为UNI :: is_unicode($数据)???
在此先感谢澄清。
PS:d @布赖恩富瓦-是的,我还没有有效的Perl编程的书-我会得到它-我保证:) /开玩笑/
is_utf8
返回关于其中使用内部存储格式信息,期限。
- 它不相关的字符串的值(尽管某些字符串只能存储在两种格式之一)。
- 它没有相关的字符串是否已被解码与否。
- 它没有相关的字符串是否包含一些已使用UTF-8或不编码。
- 这不是任何形式的有效性检查。
现在到你的问题。
整个UTF8附注是对我来说是一个谜。
use utf8;
告诉perl
源代码是使用UTF-8编码。 如果你不告诉它的话, perl
有效假定它是ISO-8859-1(作为内部机制的副作用)。
在UTF8 ::命名空间中的功能无关的编译,他们有多种用途的。
-
utf8::encode
和utf8::decode
:有用的编码和解码的功能。 编码的类似encode_utf8
和decode_utf8
,但他们就地工作。 -
utf8::upgrade
和utf8::downgrade
:很少使用,但对于XS模块周围的错误时非常有用。 更多关于这下面。 -
utf8::is_utf8
:我不知道为什么会有人曾经使用。
我怎么能保证(测试),比任何$ other_data包含有效的Unicode字符串?
什么是“有效的Unicode字符串”对你意味着什么? Unicode有针对不同情况的有效的定义不同。
出于什么目的是UTF8 :: is_utf8($数据)?
调试。 它在偷窥Perl的胆量。
在上面的例子UTF8 :: is_utf8($数据)将打印好的 - 但不明白为什么。
因为NFD碰巧选择了返回包含在UTF8 = 1种格式的字符串一个标量。
Perl有两种格式,用于存储字符串:
- UTF8 = 0可存储8位的值的序列。
- UTF8 = 1可以存储72位值的序列(尽管实际上限制在32或64位)。
第一种格式使用较少的内存和更快,当谈到访问字符串中的特定位置,但它是什么,它可以包含有限的。 (例如,它不能存储的Unicode码点,因为它们需要21位。)Perl可以在两者之间自由切换。
use utf8;
use feature qw( say );
my $d = my $u = "abcdé";
utf8::downgrade($d); # Switch to using the UTF8=0 format for $d.
utf8::upgrade($u); # Switch to using the UTF8=1 format for $u.
say utf8::is_utf8($d) ?1:0; # 0
say utf8::is_utf8($u) ?1:0; # 1
say $d eq $u ?1:0; # 1
人们通常不必担心这个问题,但也有越野车的模块。 还有,尽管剩余的Perl甚至马车的角落use feature qw( unicode_strings );
。 我们可以使用utf8::upgrade
和utf8::downgrade
改变一个标量由XS函数预期的格式。
或者是误命名和功能应该被命名为UNI :: is_unicode($数据)???
这是再好不过的。 Perl有没有办法知道一个字符串是否是一个Unicode字符串或没有。 如果你需要跟踪这一点,你需要亲自跟踪它。
在UTF8 = 0格式串可以包含Unicode代码点。
my $s = "abc"; # U+0041,0042,0043
在UTF8 = 1种格式串可以包含不Unicode代码点的值。
my $s = pack('W*', @temperature_measurements);
我怎么能保证(测试),比任何$ other_data包含有效的Unicode字符串?
你不能确定事后字符串是否具有字符语义或字节语义。 Perl并不为你追踪这一点。 你必须小心编程跟踪它:在边界编码和解码; :raw
层为字节语义, :encoding(foo)
为字符语义。 采用命名约定的变量和函数的语义之间有明显的区别,并作出错误的代码看起来是错误的。
出于什么目的是UTF8 :: is_utf8($数据)?
它告诉你的存在SvUTF8
标志,仅此而已。 这是大多数开发商几乎完全无用的,因为它是一个内部的事情。 该标志并不意味着字符串具有字符语义,它的缺失并不意味着字符串具有字节语义。
整个UTF8附注是对我来说是一个谜。
可能是因为是overdocumented,因此混乱。 大多数开发人员可以在那里是说,它的目的是使在源代码中的Unicode文本的部分后停止阅读。
在上面的例子UTF8 :: is_utf8($数据)将打印好的 - 但不明白为什么。
因为单向:: perl的这使得能够use open qw(:utf8 :std);
。 从STDIN与读取的任何输入<>
将被解码。 标准化步骤之后不改变。