2007年11月27日 13:30 [Edit]

perl - 文字列ばらしはsplit //, $strで

camel

うーん、ここがあきまへん。

[を] 転置インデックスによる検索システムを作ってみよう!
9   my @char = ($c =~ /([\x00-\x7f]|[\xC0-\xDF][\x80-\xBF]|
10                      [\xE0-\xEF][\x80-\xBF]{2}| 
11                      [\xF0-\xF7][\x80-\xBF]{3})/gsx); 

文字列をばらして(utf8の)文字一つ一つの配列にするには、バイト列に正規表現をかますのではなく、utf8文字列にしてからそれにsplit //をかますのが一番です。単にわかりやすいだけではなく、その方がずっと高速です。以下、Benchmark。

#!/usr/local/bin/perl
use strict;
use warnings;
use Benchmark qw/cmpthese timethese/;
use Encode;
print "Line to split: ";
my $bstr = <STDIN>;
my $ustr = decode_utf8($bstr);

cmpthese(
    timethese(
        0,
        {
            split => sub {
                my @chars = split //, $ustr;
            },
            map_unpack => sub {
                my @chars = map { chr } unpack "U*", $ustr;
            },
            regexp => sub {
                my @chars = (
                    $bstr =~ /([\x00-\x7f]|[\xC0-\xDF][\x80-\xBF]|
                               [\xE0-\xEF][\x80-\xBF]{2}|
                               [\xF0-\xF7][\x80-\xBF]{3})/gsx
                );
              }
        }
    )
);
% perl splitchar.pl
Line to split: こんにちは。いかがおすごしですかytoことたつをさん?
Benchmark: running map_unpack, regexp, split for at least 3 CPU seconds...
map_unpack:  3 wallclock secs ( 3.14 usr +  0.01 sys =  3.15 CPU) @ 25200.00/s (n=79380)
    regexp:  3 wallclock secs ( 3.23 usr +  0.01 sys =  3.24 CPU) @ 22480.25/s (n=72836)
     split:  3 wallclock secs ( 3.12 usr +  0.01 sys =  3.13 CPU) @ 47737.38/s (n=149418)
              Rate     regexp map_unpack      split
regexp     22480/s         --       -11%       -53%
map_unpack 25200/s        12%         --       -47%
split      47737/s       112%        89%         --

@chars = split //, $strというのは、いまいち知られていない慣用句なのですが、この際ですから覚えておきましょう。$strにutf8 flagがついていれば1 utf8文字づつ、ついていなければ(bytes semanticsであれば)1 byteづつばらします。

Dan the Perl Unicode Monger


この記事へのトラックバックURL

この記事へのトラックバック
404 Blog Not Found:perl - 文字列ばらしはsplit //, $strでで @chars = split //, $strというのは、いまいち知られていない慣用句 って書いてんだけど、知られてないの? ...と思っていたら、つい先日、utf-8文字列がus-asciiかどうか判定したいということで正規表現を使う
[Programming] 文字列のsplitって、、、【食べログ上のayucat by ayucat on tabelog】at 2007年12月01日 04:09
perl - 文字列ばらしはsplit //, $strで ところでPHP5のstr_split。 str_split (PHP 5) str_split ― 文字列を配列に変換する ただ、utf8の文字列とかだとダメっぽい。 以下、リファレンスに掲載されていた方法をまるまるコピーして。 ・・・ちょっと萎えるなぁ。 PLAIN...
PHP5のstr_split【眠る開発屋blog】at 2007年11月28日 02:48