Rubyの正規表現の/[\p{katakana}]/ ってなんなの

会社の人が書いたRubyのコードの正規表現で `/[\p{katakana}]*/`みたいなのがでてきて、なんだこれって思ったので調べた。

# へー

```rb
'アイウエオ' =~ /\A[\p{katakana}]+\z/ #=> 0
'あいうえお' =~ /\A[\p{katakana}]+\z/ #=> nil
'アイウエオあいうえお' =~ /\A[\p{katakana}]+\z/ #=> nil
'イロハニホヘトチリヌルヲ' =~ /\A[\p{katakana}]+\z/ #=> 0
'イロハニホヘトチリヌルヲワカヨタレソツネナラムウヰノオクヤマケフコエテアサキユメミシヱヒモセス' =~ /\A[\p{katakana}]+\z/ #=> 0
'ｲﾛﾊﾆﾎﾍﾄﾁﾘﾇﾙｦﾜｶﾖﾀﾚｿﾂﾈﾅﾗﾑ' =~ /\A[\p{katakana}]+\z/ #=> 0
```

# ほー

```rb
'テンノウズアイル' =~ /\A[\p{katakana}]+\z/ #=> 0
'ﾃﾝﾉｳｽﾞｱｲﾙ' =~ /\A[\p{katakana}]+\z/ #=> nil
'トウキョウテレポート' =~ /\A[\p{katakana}]+\z/ #=> nil
'ﾄｳｷｮｳﾃﾚﾎﾟｰﾄ' =~ /\A[\p{katakana}]+\z/ #=> nil
```

どうやら長音記号や半角の濁点と半濁点にはマッチしないらしい。

# 定義をしらべてみる

> また、Unicodeのプロパティ(属性情報)による文字クラス指定も可能です。 以下の記法が使えます。
> 
> * \p{property-name}
> * \p{^property-name} (否定)
> * \P{property-name} (否定)
> 
> サポートされているプロパティのリストは https://github.com/k-takata/Onigmo/blob/master/doc/UnicodeProps.txt を 参考にしてください。また、プロパティの意味は Unicode の仕様を参照してください。
>
> http://docs.ruby-lang.org/ja/2.2.0/doc/spec=2fregexp.html

URLで参照されてるテキストは、rubyが使用している Onigmo という正規表現エンジンのドキュメントらしい。

で、`katakana unicode` でググったら [Wikipediaの Katakana (Unicode Block)](https://en.wikipedia.org/wiki/Katakana_(Unicode_block)) が出てきて、「長音記号入ってるじゃん！ナンデ？？」と思ったのだけど、「長音」とか入れたら謎が解けた。全く同じ間違いをしてたのを訂正した記事が出てきた。

> 上の記事で[\p{Katakana}]に長音が含まれないのは仕様であり、正しいとの情報をいただきました。
私も今になって知ったのですが、\p{}で参照されるのは以下でいうScriptsの方であり、Blocksではないのだそうです。
http://www.unicode.org/Public/UNIDATA/Scripts.txt
http://www.unicode.org/Public/UCD/latest/ucd/Blocks.txt
おかげさまで勉強になりました。ありがとうございます!
次回にこの辺りを研究します。
> 
>　http://techracho.bpsinc.jp/hachi8833/2013_09_13/13433

で、ここで見るべきは http://www.unicode.org/Public/UNIDATA/Scripts.txt の以下の部分っぽい

```
30A1..30FA    ; Katakana # Lo  [90] KATAKANA LETTER SMALL A..KATAKANA LETTER VO
30FD..30FE    ; Katakana # Lm   [2] KATAKANA ITERATION MARK..KATAKANA VOICED ITERATION MARK
30FF          ; Katakana # Lo       KATAKANA DIGRAPH KOTO
31F0..31FF    ; Katakana # Lo  [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO
32D0..32FE    ; Katakana # So  [47] CIRCLED KATAKANA A..CIRCLED KATAKANA WO
3300..3357    ; Katakana # So  [88] SQUARE APAATO..SQUARE WATTO
FF66..FF6F    ; Katakana # Lo  [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU
FF71..FF9D    ; Katakana # Lo  [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N
1B000         ; Katakana # Lo       KATAKANA LETTER ARCHAIC E

# Total code points: 300
```

## 30A1..30FA, 30FD..30FE, 30FF

![image](https://qiita-image-store.s3.amazonaws.com/0/22333/72501090-9f23-19fd-ea29-a9ffe1a0468b.png)

よく見る `/[ァ-ヶ]/` みたいなやつと、ワ行に濁点ついたやつ、[一の字点](https://ja.wikipedia.org/wiki/%E8%B8%8A%E3%82%8A%E5%AD%97)、[「コト」の記号](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%88)。ワ行に濁点をつけるのは福沢諭吉がヴァヴィヴヴェヴォの音を表記するのに使ったんだとか。

## 31F0..31FF

![image](https://qiita-image-store.s3.amazonaws.com/0/22333/cac15320-e73e-1188-548a-6757c903391c.png)


アイヌ語に使うための（らしい）小文字のㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ

## 32D0..32FE

![image](https://qiita-image-store.s3.amazonaws.com/0/22333/8bfd0f19-b207-c617-aa20-36627c6ecbec.png)

マルつきの㋐から㋾

## 3300..3357

![image](https://qiita-image-store.s3.amazonaws.com/0/22333/22070806-aaae-f7a5-4ca6-53786beecfea.png)

㍊みたいな、ちっちゃいカタカナで一文字のスペースにおさめてあるやつ。お前らもカタカナ扱いかよ……

##　FF66..FF6F, FF71..FF9D

![image](https://qiita-image-store.s3.amazonaws.com/0/22333/16ef767d-2fba-adb4-abbd-486411a8b4b4.png)

いわゆる半角カタカナ。長音を含ませないためにFF70を飛ばした定義になっている。

## 1B000

![image](https://qiita-image-store.s3.amazonaws.com/0/22333/0662e389-e2f3-949f-3a6a-982deb1a2687.png)

𛀀。なんぞこれ……。

> 変体仮名の衣（/e/）の省略形、カタカナのア行エ。ヤ行エを「エ」と表記し、区別していた時代の表記。
> 
> https://ja.wiktionary.org/wiki/%F0%9B%80%80

というわけで、ほぼ使うことはないだろうけどいちおうカタカナらしい。

ちなみにコード表で 𛀀 の隣りにある 𛀁 (1B001) は、[や行え](https://ja.wikipedia.org/wiki/%E3%82%84%E8%A1%8C%E3%81%88) らしいです。

# まとめ

単純なカタカナと思いきや、意外とマッチする範囲が大きいわりに、カタカナで何か書くときによく使いそうな長音記号や、半角カタカナの濁点半濁点（ちなみに全角の「゛」や「゜」も
）が含まれてないという、わりと罠が多めの存在ということがわかりました。実際、会社で見かけたコードも`\p{Katakana}`のほかにいろいろ記号が補ってありました。

ちなみに、長音記号っぽい記号もまたたくさんあるので、ユーザーによる入力をバリデーションをしようとするとなかなか大変だったりするんですが、それについてはまた別の機会に……。