サロゲートとIVSの正規表現まとめ。

IVS含めたものってなかなか見ないので。

どうなんだろ。皆どうやってるんでしょね。


サロゲートのコード範囲

上位サロゲート:U+D800-U+DBFF

下位サロゲート:U+DC00-U+DFFF

IVSのコード範囲

32bit表現:U+E0100-U+E01EF

で、これの16bit表現がなかなか出てこなくて困った。

なので計算して求める。とりあえず結果。

16bit表現:U+DB40 [U+DD00-U+DDEF]


なので、正規表現は下の感じ。

// javascript

// サロゲートがあるかどうか
str.match(/([\uD800-\uDBFF][\uDC00-\uDFFF])/)

// IVSがあるかどうか
str.match(/(\uDB40[\uDD00-\uDDEF])/)

// サロゲート+IVSがあるかどうか
str.match(/([\uD800-\uDBFF][\uDC00-\uDFFF])|(\uDB40[\uDD00-\uDDEF])/)

// サロゲートを含む文字列を一文字ずつの配列にする
str.match(/([\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF])/g)

// サロゲート+IVSを含む文字列を一文字ずつの配列にする
str.match(/([\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF])(\uDB40[\uDD00-\uDDEF])?/g)

32bit表現が使える場合は下の感じ

//Python

// サロゲート+IVSを含む文字列を一文字ずつの配列にする
re.findall('([\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF])[\U000E0100-\U000E01EF]?', strs)


IVSの32bit表現を16bit表現にする計算。

計算方法:wiki : 拡張領域→サロゲートペアの項

0xE0100            1110 0000 0001 0000 0000
0xE01EF            1110 0000 0001 1110 1111

上をサロゲートペアとしてエンコーディング

①0x10000を引く

 0xE0100            1110 0000 0001 0000 0000
-0x10000            0001 0000 0001 0000 0000
=0xD0100            1101 0000 0001 0000 0000

 0xE01EF            1110 0000 0001 1110 1111
-0x10000            0001 0000 0001 0000 0000
=0xD01EF            1101 0000 0001 1110 1111

➁これを上位10ビット値と下位10ビット値に分割する。

0xD0100            1101 0000 00(0x0340)    01 0000 0000(0x0100)
0xD01EF            1101 0000 00(0x0340)    01 1110 1111(0x01EF)

➂ハイサロゲート形成として上位ビットに0xD800を加える。

 0x0340            0000 0011 0100 0000
+0xD800            1101 1000 0000 0000
=0xDB40            1101 1011 0100 0000

 0x0340            0000 0011 0100 0000
+0xD800            1101 1000 0000 0000
=0xDB40            1101 1011 0100 0000


④ローサロゲート形成として上位ビットに0xDC00を加える。

 0x0100            0000 0001 0000 0000
+0xDC00            1101 1100 0000 0000
=0xDD00            1101 1101 0000 0000

 0x01EF            0000 0001 1110 1111
+0xDC00            1101 1100 0000 0000
=0xDDEF            1101 1101 1110 1111

⑤上記から

0xE0100 ⇒ \uDB40\uDD00
0xE01EF ⇒ \uDB40\uDDEF

⑥なのでコードの範囲は下位8bitの範囲(00-EF:240個)として表現しちゃってよい(上16bit分は固定)ので下記正規表現

\uDB40[\uDD00-\uDDEF]