length()的perldoc
页面告诉我,我应该使用bytes::length(EXPR)
以字节为单位查找Unicode字符串,或者bytes页面回应此信息。
use bytes;
$ascii = 'Lorem ipsum dolor sit amet';
$unicode = 'Lørëm ípsüm dölör sît åmét';
print "ASCII: " . length($ascii) . "\n";
print "ASCII bytes: " . bytes::length($ascii) . "\n";
print "Unicode: " . length($unicode) . "\n";
print "Unicode bytes: " . bytes::length($unicode) . "\n";
但是,此脚本的输出不同于联机帮助页:
ASCII: 26
ASCII bytes: 26
Unicode: 35
Unicode bytes: 35
在我看来,length()和bytes :: length()对于ASCII和&都返回相同的值。 Unicode字符串。我的编辑器设置为默认情况下将文件写为UTF-8,所以我认为Perl将整个脚本解释为Unicode,这意味着length()会自动正确处理Unicode字符串吗?
修改:查看我的评论;我的问题并没有多大意义,因为在上面的例子中,length()不正常工作 - 它以字节为单位显示Unicode字符串的长度,而不是字符。我最初偶然发现的共鸣是一个程序,我需要在HTTP消息中设置Content-Lenth标头(以字节为单位)。我已经阅读了Perl中的Unicode,并且期望必须做一些有意义的工作,但是当length()完全返回我需要的蝙蝠时,我很困惑!有关Perl中use utf8
,use bytes
和no bytes
的概述,请参阅接受的答案。
答案 0 :(得分:22)
如果您的脚本是以UTF-8编码的,请使用utf8 pragma。另一方面,bytes pragma将强制字节语义的长度,即使字符串是UTF-8。两者都适用于当前的词汇范围。
$ascii = 'Lorem ipsum dolor sit amet';
{
use utf8;
$unicode = 'Lørëm ípsüm dölör sît åmét';
}
$not_unicode = 'Lørëm ípsüm dölör sît åmét';
no bytes; # default, can be omitted
print "Character semantics:\n";
print "ASCII: ", length($ascii), "\n";
print "Unicode: ", length($unicode), "\n";
print "Not-Unicode: ", length($not_unicode), "\n";
print "----\n";
use bytes;
print "Byte semantics:\n";
print "ASCII: ", length($ascii), "\n";
print "Unicode: ", length($unicode), "\n";
print "Not-Unicode: ", length($not_unicode), "\n";
输出:
Character semantics:
ASCII: 26
Unicode: 26
Not-Unicode: 35
----
Byte semantics:
ASCII: 26
Unicode: 35
Not-Unicode: 35
答案 1 :(得分:4)
bytes
pragma的目的是替换当前作用域中的length
函数(以及其他几个与字符串相关的函数)。因此,对您计划中length
的每次通话都是对length
提供的bytes
的调用。这更符合您的尝试:
#!/usr/bin/perl
use strict;
use warnings;
sub bytes($) {
use bytes;
return length shift;
}
my $ascii = "foo"; #really UTF-8, but everything is in the ASCII range
my $utf8 = "\x{24d5}\x{24de}\x{24de}";
print "[$ascii] characters: ", length $ascii, "\n",
"[$ascii] bytes : ", bytes $ascii, "\n",
"[$utf8] characters: ", length $utf8, "\n",
"[$utf8] bytes : ", bytes $utf8, "\n";
你的推理中另一个微妙的缺陷是存在Unicode字节这样的东西。 Unicode是字符的枚举。例如,它说U + 24d5是&#x24d5(CIRCLED LATIN SMALL LETTER F); Unicode没有指定字符占用的字节数。这留给了编码。 UTF-8表示它占用3个字节,UTF-16表示占用2个字节,UTF-32表示需要4个字节,等等。这是comparison of Unicode encodings。 Perl默认使用UTF-8作为字符串。对于前127个字符,UTF-8具有与ASCII相同的各种优点。
答案 2 :(得分:1)
我发现可以使用Encode模块来影响长度的工作方式。
如果$ string是utf8编码的字符串。
编码:: _ utf8_on($字符串); #length函数将显示此后的代码点数。
编码:: _ utf8_off($字符串); #length函数将在此后显示字符串中的字节数。