NeverBlog::Likk::Unexistable;

見なかったことにして下さい

Text::BreakIterator::UTF8

ネタ元[を] Perl で日本語テキストを字種分割

以前Text::BreakIteratorというEUCJPな文字種分割モジュールが http://perl.infoware.ne.jp/にあったんですが、どうもなくなってしまったので、それのUTF8版を置いておきます。

package Text::BreakIterator;
use strict;

sub new
{
    my $class = shift;
    my $string = shift;
    my $self = bless {
        string  => $string,
        pattern => undef,
        pos     => 0,
    }, $class;
    $self->{pattern} = $self->pattern;
    $self;
}

sub pattern
{
    qr/(
        \s+       | # Space
        [0-9]+    | # Number
        [A-Za-z]+ | # alphabet
        .                               # Other
    )/x;
}

sub next
{
    my $self = shift;
    my $type;
    pos($self->{string}) = $self->{pos};
    $self->{string} =~ m/\G$self->{pattern}/g;
    $self->{pos} = pos $self->{string};
    return $1;
}

sub close
{
    my $self = shift;
    $self->{string} = undef; # $self;
}
1;
package Text::BreakIterator::UTF8;
use strict;
use base qw/Text::BreakIterator/;

sub pattern
{
    qr/(
        \s+									| # Space
        \p{Latin}+							| # Latin
        \p{InCJKSymbolsAndPunctuation}+		| # Symbol
        \p{InBasicLatin}+					| # Eisuu
        \p{InHiragana}+						| # Hiragana
        \p{InKatakana}+						| # Katakana
        \p{Greek}+							| # Greek
        \p{Cyrillic}+						| # Cyril
        \p{BoxDrawing}+          			| # Keisen
        \p{Han}+   							| # Kanji
        .                               # Other
    )/x;
}

1;

都合上、Text::BreakIteratorと、Text::BreakIterator::UTF8二つに分けてます。
Text::BreakIterator::UTF8が、Text::BreakIteratorをuse baseしてます。

使い方はこんな感じ。

use Text::BreakIterator::UTF8;
use utf8;
my $string = Text::BreakIterator::UTF8->new(qq|ルーラでう、う9 10AB.DE「"GH'」★で漢字をカ・ナ食ったー!?MJD39?。|);
binmode(STDOUT, ":utf8");
my @list = ();
while (my $chunk = $string->next) { push @list, $chunk }
print join ',', @list;      

出力結果

ルーラ,でう,、,う,9 10AB.DE,「,"GH',」,★,で,漢字,を,カ・ナ,食,った,ー,!?,MJD,39?,。

平仮名カタカナ漢字部分も容赦なくぶった切っているので、ネタ元の出力意図とは違う形ですが、まあその辺りはご容赦を。

テキストの文字種分割の補足 - daily dayflowerを見て、直したい部分色々ありますので、後で修正するかも。