Конвертировать строку UTF8 в числовые значения в Perl - PullRequest
6 голосов
/ 22 августа 2010

Например,

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

Я хочу распечатать числовые значения

20013,22283,99

Ответы [ 4 ]

13 голосов
/ 23 августа 2010

unpack будет более эффективным, чем split и ord, потому что он не должен создавать кучу временных 1-символьных строк:

use utf8;

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

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

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

Быстрый тест показывает, что он примерно в 3 раза быстрее, чем split+ord:

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 голосов
/ 22 августа 2010

Для того, чтобы 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;
3 голосов
/ 22 августа 2010

См. perldoc -f ord :

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

Или сжато в одну строку: my @chars = map { ord } split //, $str;

Данные :: Dumper ed, это производит:

$VAR1 = [
          20013,
          22283,
          99
        ];
2 голосов
/ 10 января 2014

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;
...