読者です 読者をやめる 読者になる 読者になる

preg系正規表現のUnicodeプロパティ、スクリプト、ブロックの挙動

PHP

PHP4でうまいこと楽に漢字を判別できたらいいなぁ、と思ったのが発端で調べてみたメモ。なんでpreg系限定化というと、ereg→そもそも2バイト文字非対応、mb_ereg→マニュアル適当すぎて調べる気失せたため。あとそれ以前にPHP4ではUnicodeプロパティとか使えるのはたぶんpreg系だけ。

PHPは4.4.7。Windows。ソースはEUC-JPで記述。TagetやPatternはpreg_match_allに渡す前に、mb_convert_encodingでUTF-8に変換している。表示時は逆にEUC-JPに戻してから表示(今書いてるPHPアプリがEUC-JPなためこんな面倒なことをしている)。

参考 : 日本語に絡むUnicodeブロックとスクリプト(正規表現)

preg_match_allに、uオプション付きの正規表現を与え、Unicodeプロパティ、スクリプト、ブロックを与えてみる。

なお、半角スペース、全角スペース、タブ、改行など、文字として見づらいものは角括弧表記で代替してます。

\p{L} : 表示可能な文字

Target:0aB#1cDあぇカォ亜%ウッ゛〜[SPACE][Full-Width-SPACE][TAB][CR][LF]
Pattern:/\p{L}/msu
Matches:aBcDあぇカォ亜ウッ

\p{M} : 他の文字と組み合わせて使用する文字

Target:0aB#1cDあぇカォ亜%ウッ゛〜[SPACE][Full-Width-SPACE][TAB][CR][LF]
Pattern:/\p{M}/msu
Matches:

\p{Z} : 区切り文字

Target:0aB#1cDあぇカォ亜%ウッ゛〜[SPACE][Full-Width-SPACE][TAB][CR][LF]
Pattern:/\p{Z}/msu
Matches:[SPACE] 

\p{S} : 記号

Target:0aB#1cDあぇカォ亜%ウッ゛〜[SPACE][Full-Width-SPACE][TAB][CR][LF]
Pattern:/\p{S}/msu
Matches:゛

\p{N} : 数字

Target:0aB#1cDあぇカォ亜%ウッ゛〜[SPACE][Full-Width-SPACE][TAB][CR][LF]
Pattern:/\p{N}/msu
Matches:01

\p{P} : 句読点

Target:0aB#1cDあぇカォ亜%ウッ゛〜[SPACE][Full-Width-SPACE][TAB][CR][LF]
Pattern:/\p{P}/msu
Matches:#%〜

\p{C} : L,M,Z,S,N,P以外のすべての文字

Target:0aB#1cDあぇカォ亜%ウッ゛〜[SPACE][Full-Width-SPACE][TAB][CR][LF]
Pattern:/\p{C}/msu
Matches:[TAB][CR][LF]

\p{Ll} : 小文字

Target:0aB#1cDあぇカォ亜%ウッ゛〜[SPACE][Full-Width-SPACE][TAB][CR][LF]
Pattern:/\p{Ll}/msu
Matches:ac

\p{Lu} : 大文字

Target:0aB#1cDあぇカォ亜%ウッ゛〜[SPACE][Full-Width-SPACE][TAB][CR][LF]
Pattern:/\p{Lu}/msu
Matches:BD

\p{Lo} : ヘブライ語や日本語などの大文字と小文字を持たない文字

Target:0aB#1cDあぇカォ亜%ウッ゛〜[SPACE][Full-Width-SPACE][TAB][CR][LF]
Pattern:/\p{Lo}/msu
Matches:あぇカォ亜ウッ

\p{Sc} : 通貨記号

Target:0aB#1cDあぇカォ亜%ウッ゛〜[SPACE][Full-Width-SPACE][TAB][CR][LF]
Pattern:/\p{Sc}/msu
Matches:

\p{Katakana} : カタカナ

Target:0aB#1cDあぇカォ亜%ウッ゛〜[SPACE][Full-Width-SPACE][TAB][CR][LF]
Pattern:/\p{Katakana}/msu
Matches:カォウッ

\p{Hiragana} : ひらがな

Target:0aB#1cDあぇカォ亜%ウッ゛〜[SPACE][Full-Width-SPACE][TAB][CR][LF]
Pattern:/\p{Hiragana}/msu
Matches:あぇ

\p{Han} : 漢字

Target:0aB#1cDあぇカォ亜%ウッ゛〜[SPACE][Full-Width-SPACE][TAB][CR][LF]
Pattern:/\p{Han}/msu
Matches:亜

\p{Latin} : 英数字

Target:0aB#1cDあぇカォ亜%ウッ゛〜[SPACE][Full-Width-SPACE][TAB][CR][LF]
Pattern:/\p{Latin}/msu
Matches:aBcD

\p{Common} : スペースや句読点

Target:0aB#1cDあぇカォ亜%ウッ゛〜[SPACE][Full-Width-SPACE][TAB][CR][LF]
Pattern:/\p{Common}/msu
Matches:0#1%゛〜[SPACE] [TAB][CR][LF]

記号とかいって濁点しかマッチしなかったり、なんかイメージと違う結果が出まくってるが、きっとUnicodeプロパティの定義とか見れば納得いくのだろう(面倒なので参考先サイトしか見ていない)。

とりあえずp{Han}で漢字だけとれそうなのがわかったので満足。ちなみにUnicodeブロックはWarning出て動作しなかった。

2008/06/05追記

大まかな動作を知りたかっただけなのでテスト文字列の選別がかなり適当。本当なら全ての記号を洗い出して実験すべき。