さわだのノート

書籍のお仕事に役立つかもしれない思いつきを記録しています。

RSS: 記事の更新情報 Rss Feed

Unicodeブロックを利用する

実家はいまだに携帯電話がまともに通じず、インターネットもないという情報鎖国状態でした。眼は休まったけど、やっぱりネットがないと落ち着きません。

さて、前回PerlUnicode文字列に対する正規表現検索がなにやらちょっと変わった動作をするというお話を書きました。それに関連して、「Unicodeブロック」という機能がPerl正規表現検索では利用できるようです。「\p{hoge}」と記述することで、Unicodeで定義されている文字のブロックが使えるのだそうです。

要するに、漢字やひらがな、カタカナの文字だけにヒットする正規表現が簡単に書けるということです。正直なところ、詳しくは僕もよくわかりません。

メタ文字 説明
\p{N} 全角・半角数字
\p{LC} 大文字・小文字のある文字(半角・全角両方)
\p{Lu} 大文字の文字(半角・全角両方)
\p{Ll} 小文字の文字(半角・全角両方)
\p{Latin} アルファベット(半角・全角両方)
\p{InBasicLatin} 半角英数字と半角記号
\p{InHiragana} ひらがな
\p{InKatakana} カタカナ
\p{InCJKUnifiedIdeographs} 漢字
\p{InCJKSymbolsAndPunctuation} 全角記号
\p{InHalfwidthAndFullwidthForms} 半角カナ、全角英数など

こんな感じで文字種ごとに検索ができるようになっています。
とりあえず日本語に関連しそうな項目を抜き出してみましたが、ほかにもたくさんあるようです。

perlunicode - Perl における Unicode サポート 【perldoc.jp】

この中から、従来の「\w」と同じ挙動をしそうなものを探してみると……ないですね。そんなときの場合に、Perlでは自分でUnicodeブロックを定義することも可能となっています。下記の例では、半角数字だけにヒットする「InNumber」と、半角英数字だけにヒットする「InWordNum」を定義してみました。

#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use feature qw/say switch/;

use open IO => qw/:utf8 :std/;

$_ = 'Androidマーケットのアプリ Appliを§, 10〜20インストールして$12。';

my @eisu2 = m|\p{InWordNum}|g; #[a-zA-Z0-9]と同じ
my @suji2 = m|\p{InNumber}|g;  #[0-9]と同じ

say '@eisu2'; say @eisu2;
say '@suji2'; say @suji2;

sub InNumber {
    return << "EOM";
+utf8::N
-utf8::InHalfwidthAndFullwidthForms
EOM
}

sub InWordNum {
    return << "EOM";
+utf8::InBasicLatin
-utf8::S
-utf8::Z
-utf8::P
EOM
}

f:id:takepierrot:20120104213326p:image
実行してみると、ちゃんと検索できていますね。
これくらいならコメントに書いた方法でやったほうが確実かもしれませんが……。

同じような方法で、ひらがな・カタカナ・漢字の文字列だけにヒットする、半角カタカナだけにヒットするといったUnicodeブロックも定義できちゃうわけですね。[ア-ン]とか[あ-ん]とかでも代用はできるのかもしれませんが、こちらの方が確実です。複雑な条件も指定しやすそう。

その代わり、目的の文字列を指すUnicodeブロックがどれなのかを探すのが少々面倒です。