2009年1月22日星期四

[PerlChina] Re: 如何计算utf8字符串长度,把中文字按两字符长度算?????

2009/1/22 agentzh <agentzh@gmail.com>
2009/1/22 agentzh <agentzh@gmail.com>

以字符语义编历串,如果是 ascii 则按 1 计算之(有专门的正则 group),否则算 2 不就结了?

For the record:

$ perl -MEncode -e 'for (split //, Encode::decode "utf8",shift) { if (/[[:ascii:]]/) { $c++ } else { $c+=2 } }print $c' '你b好'
5

把 Perl 的 one-liner 写得这么长,确实挺丢脸的:

    $ perl -MEncode -e '$_=shift;Encode::_utf8_on($_);while (/[[:ascii:]]/g) { $a++ }print $a+2*(length($_)-$a)' '你b好'
    5
 
这个效率应该会高不少,特别是大串。

呃。。。还可以更短一些:

    $ perl -MEncode -e '$_=shift;Encode::_utf8_on($_);s/[[:ascii:]]/$a++/eg;print $a+2*(length($_)-$a)' '你b好'
    5

不过这种形式未必更快。。。Benchmark welcome!

还可以更短一些!

    $ perl -MEncode -e '$_=shift;Encode::from_to($_,"utf8","gbk");print length $_' '你b好'
    5

这种形式应该是最快的。。。呵呵。。。借用 GBK 中非 ASCII 都是 2 个字节的特点。。。

呃。。。如果要写成函数的话,可以这么写(以最短的那个 one-liner为例):

use Encode qw( from_to );

sub visual_length ($) {
    my $s = shift;
    from_to($s, 'utf8', 'gbk');
    length $s;
}

print visual_length "你b好";

Cheers,
-agentzh



--~--~---------~--~----~------------~-------~--~----~
您收到此信息是由于您订阅了 Google 论坛"PerlChina Mongers 讨论组"论坛。
 要在此论坛发帖,请发电子邮件到 perlchina@googlegroups.com
 要退订此论坛,请发邮件至 perlchina+unsubscribe@googlegroups.com
 更多选项,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问该论坛

-~----------~----~----~----~------~----~------~--~---

没有评论: