There's an echo in my head

日々のメモ。

Unicodeブロック/スクリプトを使うと日本語の正規表現に便利

Oniguruma(CRuby 1.9系組み込み)とOnigumo(CRuby 2.0系組み込み)で利用できるUnicodeブロックおよびUnicodeスクリプトを使うと、日本語(というか多バイトの文字列)に対する正規表現が手軽に書ける。

例えば\p{N}は全角半角にかかわらずアラビア数字にマッチする。Unicode 6.0だと四角い囲いのついた数字は数字と囲い記号の結合で表わされるけども、この数字の部分にもマッチする。

/\p{N}/ =~ "1"  #=> 0
/\p{N}/ =~ "" #=> 0
/\p{N}/ =~ "\u{0030 20E3}" #=> 0 

他にもアルファベットだと\p{Alphabetic}、小文字だけなら\p{Lowercase}とか。なにが使えるかはOnigurumaのREADMEのCharacter Propertyとか、OnigumoのUnicodeProps.txtに載ってる。

で、日本語だとなにを使うのかというと、ひらがなに\p{Hiragana}、全角カタカナに\p{Katakana}、漢字には\p{Han}である。

/\p{Hiragana} =~ /あ/ #=> 0
/\p{Katakana} =~ /ア/ #=> 0
/\p{Han} =~ /猫/ #=> 0

ちなみに\p{Katakana}は半角カタカナにはマッチしない。半角カタカナにマッチさせるなら別途\p{InHalfWidthAndFullWidthForms}を使う。ただしOnigurumaはこれに対応していないので、コードの範囲(半角のヲから半角の半濁点まで)を直接ベタ書きする必要がある。

おまけ。\p{S}は「$」や「&」といった全角・半角の記号にマッチだけでなく、Unicode 6.0で導入された絵文字にもマッチする。ただガラケー時代の絵文字や、iOS4系以前のSoftbank絵文字、Android3系以前のGoogleの絵文字は私用領域に乗っかっていたはずなのでマッチしないはず。もし絵文字を除外したいという要求があるなら、ブラックリストよりもなにを通すかのホワイトリストを作ったほうが良さそう。

参考

このブログに出てくるコードスニペッツは、引用あるいは断りがない限りMITライセンスです。