QA@IT

UTF8で全角文字を表す正規表現

8830 PV

UTF8で全角文字を表す正規表現というのは、どう書くのが正解でしょうか? 言語はRubyを想定しています。

  • 言語は何をお使いですか? -
  • 言語はRubyを想定しています -

回答

正規表現の文字クラスに名前がついているもののリストに「全角文字」がないので、moji を使ってることが多いです。

http://gimite.net/gimite/rubymess/moji.html

require 'moji'
'Ruby1.8.7で動くRuby on Railsのlatestバージョンは?'.scan(/#{Moji.zen}+/)
 => ["1.8", "で動く", "Railsの", "は"] 

追記:
Mojiの中を見ると、

ZEN
JISに含まれる全ての全角文字。
(({ZEN_SYMBOL | ZEN_ALNUM | ZEN_KANA | ZEN_GREEK | ZEN_CYRILLIC | ZEN_LINE | ZEN_KANJI}))

ZEN_KANJI = uni_range(0x3400, 0x4dbf, 0x4e00, 0x9fff, 0xf900, 0xfaff) || /[亜-瑤]/

ZENは記号や英数、カナ、ギリシャ文字、キリル、罫線、漢字あたりのクラスを指定してくれているようです。ZEN_KANJIは、

ということのようです。Extension AとかHan Characterは、日本語テキストを扱う分には関係なさそうな気もしますが……。ともあれ、実用上はこれで十分。

編集 履歴 (3)
  • ありがとうございます! Mojiのコードにある文字クラスの情報を追記しました。 -

「全角ってなんですか?」 (c)void

まぁ、アクセント記号付きアルファベットとか本気で悩みどころなんですが、
とりあえず \P{ASCII} とかでいいんじゃないの説も

編集 履歴 (0)

要件によるとは思うのですが,Unicodeにおいて厳密に「全角」「半角」を弁別するのであれば Unicode Character DatabaseEast Asian Widthを考慮することになります。
Wikipedia ソースですが東アジアの文字幅によくまとまっています。

Python や Perl の場合,(現代の)処理系にはUnicode Character Databaseが添付されているのでわりと組みやすい (とはいえ「正規表現」だけでは難しい) ですが,Ruby の場合はなさそうですね。
github にちらほらと UCD をサポートするプロジェクトも見受けられますが,定番はないのかな?
日本の方のブログ記事でRubyとPythonで全角文字を半角文字2文字として数える その2 - _dog (underdog)というものもありました。

ちなみに Perl では正規表現のプロパティを後付で追加できる?ので,CPAN モジュールの Unicode::EastAsianWidth を利用すると正規表現で全角文字を表すことができます。このプロダクトは EastAsianWidth.txt から文字範囲を生成しているみたいです。

編集 履歴 (0)
  • なるほど、East Asian Widthというのがあるのですね、知りませんでした。興味深いポインタ、ありがとうございます。勉強になりました -
  • ActiveSupport の multibyte/unicode.rb で使っているデータが同 values/unicode_tables.dat にmarshalダンプした形で置かれていますが、 East Asian Width 属性の情報は入っていませんでした。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。