2010-08-22 111 views
6

例如,轉換UTF8字符串轉換成數值在Perl

my $str = '中國c'; # Chinese language of china 

我想打印出來的數值

20013,22283,99 
+2

「中國的中國語言」?爲什麼'中國'? – Zaid 2010-08-22 20:19:40

+1

我想它應該讀*中文單詞「中國」*。 – daxim 2010-08-23 09:39:42

回答

13

unpack將比splitord更高效,因爲它不必讓一幫暫時1字符串:

use utf8; 

my $str = '中國c'; # Chinese language of china 

my @codepoints = unpack 'U*', $str; 

print join(',', @codepoints) . "\n"; # prints 20013,22283,99 

快速基準測試顯示它比split+ord快3倍左右:

use utf8; 
use Benchmark 'cmpthese'; 

my $str = '中國中國中國中國中國中國中國中國中國中國中國中國中國中國c'; 

cmpthese(0, { 
    'unpack'  => sub { my @codepoints = unpack 'U*', $str; }, 
    'split-map' => sub { my @codepoints = map { ord } split //, $str }, 
    'split-for' => sub { my @cp; for my $c (split(//, $str)) { push @cp, ord($c) } }, 
    'split-for2' => sub { my $cp; for my $c (split(//, $str)) { $cp = ord($c) } }, 
}); 

結果:

   Rate split-map split-for split-for2  unpack 
split-map 85423/s   --  -7%  -32%  -67% 
split-for 91950/s   8%   --  -27%  -64% 
split-for2 125550/s  47%  37%   --  -51% 
unpack  256941/s  201%  179%  105%   -- 

的差異不太明顯與較短的字符串,但unpack仍然是兩倍以上的速度。 (split-for2比其他分裂速度更快一點,因爲它不建立碼點的列表。)

3

perldoc -f ord

foreach my $c (split(//, $str)) 
{ 
    print ord($c), "\n"; 
} 

或壓制成單行:my @chars = map { ord } split //, $str;

Data::Dumper版,這將產生:

$VAR1 = [ 
      20013, 
      22283, 
      99 
     ]; 
3

要讓UTF8在源代碼中承認的,你必須use utf8;事先:

$ perl 
use utf8; 
my $str = '中國c'; # Chinese language of china 
foreach my $c (split(//, $str)) 
{ 
    print ord($c), "\n"; 
} 
__END__ 
20013 
22283 
99 

以上簡潔,

print join ',', map ord, split //, $str; 
2

http://www.perl.com/pub/2012/04/perlunicook-standard-preamble.html

#!/usr/bin/env perl 


use utf8;  # so literals and identifiers can be in UTF-8 
use v5.12;  # or later to get "unicode_strings" feature 
use strict; # quote strings, declare variables 
use warnings; # on by default 
use warnings qw(FATAL utf8); # fatalize encoding glitches 
use open  qw(:std :utf8); # undeclared streams in UTF-8 
# use charnames qw(:full :short); # unneeded in v5.16 

# http://perldoc.perl.org/functions/sprintf.html 
# vector flag 
# This flag tells Perl to interpret the supplied string as a vector of integers, one for each character in the string. 

my $str = '中國c'; 

printf "%*vd\n", ",", $str;