ES2018で入ったUnicode property escapes in regular expressionsを調べてみた
はじめに
ES2018で正規表現まわりの機能にいくつかの便利な表現が入った。
例えばこんな感じ。
いずれもChrome*1 のコンソールで入力して試すことができる。
// `ひらがな` のみの文字列ならtrue /^\p{sc=Hiragana}+$/u.test('あいうえお') // true // `カタカナ` のみの文字列ならtrue /^\p{sc=Katakana}+$/u.test('アイウエオ㍑㍍') // true // `漢字` のみの文字列ならtrue /^\p{sc=Han}+$/u.test('𠮷野家') // true // `漢字` 以外が含まれているのでfalse /^\p{sc=Han}+$/u.test('㍻㍼') // false // `漢字っぽい文字` のみの文字列ならtrue /^\p{scx=Han}+$/u.test('平成昭和㍻㍼') // true
使い方
unicode property escapes を使うには RegExp
オブジェクト生成時に u
フラグを渡す必要がある。
次に \p{sc=Hiragana}+
のように \p
から始めると ひらがな にマッチし、 \P{sc=Hiragana}+
のように \P
から始めると ひらがな以外 にマッチする。
書式について
// positive match \p{UnicodePropertyName=UnicodePropertyValue} // negative match \P{UnicodePropertyName=UnicodePropertyValue}
という書式で指定する。
では UnicodePropertyName
と UnicodePropertyValue
に指定できるものは何か調べてみた。
UnicodePropertyName
UnicodePropertyName に指定できるものは以下の通り。
General_Category
(gc
)Script
(sc
)Script_Extensions
(scx
)- プラスして、Binary Unicode property (後述) というのを指定できる
General_Category
General_Category は特定の言語(英語、日本語、フランス語など)に依存しない、全般的な文字が属するカテゴリーが定義されている。
以下は General_Category が取りうる値の一例。
Letter
(L
)aAあア亜
など文章に使うような文字は true になる*2*-2[.㍑㍼\\
など数値や記号のような文字は false になる
Number
(N
)1234①
などの数字としての意味を持つ文字は true になる²³¹¼½¾𝟏𝟐𝟑𝟜𝟝𝟞𝟩𝟪𝟫𝟬𝟭𝟮𝟯𝟺𝟻𝟼㉛ⅠⅡⅢⅣⅤⅪⅫⅬⅭⅮⅯⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹⅺⅻⅼⅽⅾⅿ
- これらも true になるので、思ったより多くの文字が該当する
'一壱aI=あ'
などの数字として使えない文字は false になる
Symbol
(S
)⒜🄐☟☡☤㏪😀
などの記号としての意味を持つ文字が true になる
また General_Category は書式でいうところの UnicodePropertyName を省略して書くことができる。
たとえば以下のコードはすべて同じ結果になる。
// 通常のフォーマットに則るとこう書く /^\p{General_Category=Letter}+$/u.test('abcABCあいうサシスハンカク') // true // `General_Category` は `gc` と省略できる /^\p{gc=Letter}+$/u.test('abcABCあいうサシスハンカク') // true // `General_Category` はプロパティ名自体省略できる /^\p{Letter}+$/u.test('abcABCあいうサシスハンカク') // true
General_Category
にどんな Value を指定できるかについてはこちら。
Script, Script_Extensions
General_Category はどんな言語においても共通するような値が定義されていたのに対して、Script というのは言語(英語、日本語、フランス語など)特有の文字が定義されている。
日本語に関して言えば Hiragana
(Hira
) , Katakana
(Kana
) , Han
などが使いやすそうである。
// `ひらがな` のみの文字列で構成されているか /^\p{sc=Hiragana}+$/u.test('あいうえお') // true // `カタカナ` のみの文字列で構成されているか /^\p{sc=Katakana}+$/u.test('アイウエオ㍑㍍') // true // `漢字` のみの文字列で構成されているか ^\p{sc=Han}+$/u.test('𠮷野家') // true
Script_Extensions とはある Script に属する文字を、別な Script でも使えるように拡張したものである。
簡単な例を挙げると、
// 1. /^\p{sc=Hira}+$/u.test('るびー') // false // 2. /^\p{scx=Hira}+$/u.test('るびー') // true
ー
(伸ばし棒)が Script=Hiragana に属さないため false になるー
(伸ばし棒)が Script_Extensions=Hiragana,Katakana に属しているため true になる
Script_Extensions (Unicode)についてとても分かりやすく解説されている記事があったので、詳しくはこちらを参照してほしい。
JavaScriptのUnicode Property Escapesについての補説
Binary Unicode property
Binary Unicode property とはある Unicode の文字に付随している YES / NO で設定される属性のことである。
binary
という意味の通りプロパティの値は YES or NO になる。
UnicodePropertyValue
を省略して書くので、書式はこのようになる。
// positive match \p{BinaryUnicodePropertyName} // negative match \P{BinaryUnicodePropertyName}
こんな感じで指定できる。
// ASCII 文字のみで構成されているか /^\p{ASCII}+$/u.test('abcde*10') // true // 絵文字が含まれているか /\p{Emoji}+/u.test('robot 🤖!') // true // 大文字のみで構成されているか /^\p{Uppercase}+$/u.test('AAAA') // true // 空白が含まれているか /\p{space}+/u.test(' ') // true
指定できるPropertyの一覧はこちら。
https://tc39.github.io/proposal-regexp-unicode-property-escapes/#table-binary-unicode-properties
※ Unicode 側で binary property が設定されていても、JS 側で参照できる(実装されている)とは限らないので、利用するときは上記の一覧を一度見ておいたほうがいい。
調べ方
UnicodePropertyValue に属する文字一覧を調べる
こちらから調べることができる。
http://unicode.org/cldr/utility/properties.jsp
例えば Script=Hiragana に属する文字一覧を見たい場合は、上記リンクより General > Catalog > Script
の SHOW VALUES のリンクを開く。
次に Hiragana
で検索するか、General > Catalog > Script
にある Hiragana (Hira)
のリンクを開く。
これで Script=Hiragana に属する文字の一覧が見れる。
(ゖ
: ひらがなの小文字の け
などがあって発見がある。)
ある文字に指定されている属性を調べる
こちらから調べることができる。
Unicode Utilities: Character Properties
たとえば ー
(伸ばし棒) を検索すると、
- Unicode上の名前は
KATAKANA-HIRAGANA PROLONGED SOUND MARK
という - Unicode v1.1 で追加された
- Script=Common に属する
- 様々な binary property が設定されている
などがわかる。
おわりに
ES2018 では正規表現まわりの機能が強化され、JS でも正規表現で UnicodePropertyName を使えるようになった*3。
これによって読みにくくなりがちであった正規表現が読みやすくなるかもしれない。
今回この機能を調べるにあたり Unicode についても理解が深まった。
特に絵文字まわりが難しかったのでまたの機会にまとめてみようと思う。