Javaでサロゲートペア文字を置換したり除去する2つの方法

java-surrogate
  • URLをコピーしました!

前回、JavaASCII制御文字の取り扱いについて記事にしました。
そして今回は、前回の対策を応用して、もっと厄介なサロゲートペア文字Javaでゴニョゴニョする方法を2つ程ご紹介したいと思います。

minory
JavaでASCIIの制御文字を置換する3つの方法 | minory 今までJavaに関する記事を投稿したことはありませんが、仕事で少しだけ文字コードの変換を行う際に使いましたので、記事にしたいと思います。何分、Javaに関しては初心者で...

目次

サロゲートペア文字とは?

簡単に説明すると、全世界で文字コードを統一するため、Unicodeという文字コードが一般的に主流になっています。
通常1文字を2バイトで表現するのですが、2バイト(65536文字)では文字が足りなくなってしまったため、1文字を4バイトで表現する方法として「サロゲートペア」が誕生しました。

CodeZine
サロゲートペア入門 Windows VistaのJIS2004対応により、WindowsのUnicode環境で使用できる日本語漢字が907字追加されました。しかしこの中には「サロゲートペア」と呼ばれる文字が含まれてお...

サロゲートペアは何が問題なの?

今ではそんなに意識することはなくなりましたが、古いシステムや古いデータを取り扱う際に問題が発生してしまいます。
と言うのも、昔はUnicode以外の文字コードも多く使われていました。
それ故にバグ、いわゆる文字化けが発生してしまうのです。
これによって、データの不整合が起きたり、プログラムが想定したとおりに動かなかったりします。

サロゲートペア文字一覧

実際、サロゲートペア文字にはどのような文字があるのか、Qiitaの記事をご覧ください。

Qiita
Java サロゲートペア文字数カウント - Qiita JavaでTwitterのような140文字制限をかけようとするときに考える必要がある。サロゲートペアについて。サロゲートペアとはサロゲートペアとは、16 ビット符号単位の組によ...

サロゲートペア文字を置換・削除する方法

前回のASCII制御文字の方法を応用して、2つの方法でサロゲートペア文字を変換していきます。
以下の2つの例では、「𩸽(ほっけ)」サロゲートペア文字を「(くち)」という漢字に置換します。

1. 正規表現を利用する

前回ご紹介したJava正規表現一覧が掲載されている海外のサイトを見ると「Unicode Categories」にサロゲートペア文字を判定する正規表現がありました。
https://regular-expressions.mobi/unicode.html?wlr=1

p{Cs}p{Surrogate}どちらでも同じ動きをするようですね。
これをreplaceAll()で使うとこんな感じです。

そして、変換してみた結果がこれ。

2文字になった!?
なるほど…。
前述の通り、通常1文字を2バイトで表現しているので、1文字4バイトであるサロゲートペア文字2文字扱いになってしまうようです。
そこで、上位サロゲート下位サロゲートに分けて変換することにします。同じく上記のサイトを見ると「Unicode Blocks」の92.と94.に上位サロゲートInHigh_Surrogates)と下位サロゲートInLow_Surrogates)を判定する正規表現がありました。
この辺りです。

上位サロゲートだけ、または下位サロゲートだけ変換してしまうと、どちらかの2バイト分が残ってしまうので、片方は削除します。

上記の例では、上位サロゲート置換し、下位サロゲート空文字にしました。
当然、結果は1文字で思った通りになりました。

ただ削除するだけの場合は、前者の方法で1発で便利ですね。
置換する場合は後者の方が応用が利くかもしれません。

2. 1文字ずつ判定する

続いて、こちらも前回の応用で、1文字ずつループしてサロゲートペア文字を判定します。
判定方法はJavaCharacterクラスに用意されている以下の関数を使います。

  • isSurrogate()
  • isHighSurrogate()
  • isLowSurrogate()

詳しくはこの辺りを参考にしてね!

あわせて読みたい

前回同様、関数を作ってみました!

もちろん、これだけだと正規表現と同じように「口口」2文字になってしまいますね。
ですので、こちらも同じように上位サロゲートのみ置換下位サロゲート空文字にしてしまいましょう。
以下、抜粋。

または、上位サロゲート置換した後、ループを進めて下位サロゲート無視する方法もありますね!

以上、こんな感じでいかがでしたでしょうか。
方法は1つじゃないですね。
前回も書きましたが、正規表現は遅いらしいですが、コンマ何秒の世界なので自分は好きな方で良いと思います。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次