2013-02-20 12 views
7

は私のデータベースでは、私は4バイトを知っているようにUnicodeは法的私のJavaがあるエラーチェックUTF-8データ型の3バイト、または4バイトのUnicode

​​

私は、JavaとMySQL 5を使用して、取得しますMySQL 5では違法ですが、問題が発生する可能性があり、データのタイプをチェックしたいと思います。 UTF-8データが3バイトまたは4バイトのUnicodeであることを確認するにはどうすればよいですか?

+0

私はあなたの列のデータ・タイプの長さの制限、あなたが最初に挿入しようとしているデータのサイズを見てお勧めします。 'VARCHAR'に100K文字を挿入している場合は、エンコーディングに誤りはありません。 – Jon

+0

4バイトのUTF-8エンコードされた文字がこの問題の原因だとは思わない。 UTF-8エンコード時に* m *バイト(* m *> * n *)を使用するが、VARCHAR(* n *)に入れる必要がある* n *文字列が原因である可能性が高くなります。 –

+0

@Jonまず最初にチェックしたが、それは問題ではなかったが、私はすでに解決していたが、今後もエンコーディングのチェックを使うつもりだと思う。 – akuzma

答えて

15

UTF-8は、すべて基本的な多言語プレーン(つまりU + 0000からU + FFFFまで)のすべてを1-3バイトでエンコードします。したがって、文字列のすべてがBMPのであるかどうかを確認するだけです。 Javaでは

、それは、Java非BMP文字をエンコードするためにサロゲートペアを使用するように(UTF-16コード単位である)任意charは、高または低サロゲート文字であるかどうかをチェックする手段:

public static boolean isEntirelyInBasicMultilingualPlane(String text) { 
    for (int i = 0; i < text.length(); i++) { 
     if (Character.isSurrogate(text.charAt(i))) { 
      return false; 
     } 
    } 
    return true; 
} 
10

あなたはあなただけのMySQLにそれを渡す前に、それらの文字を削除することができ、BMPを超えてサポートしたくない場合は、次の

public static String withNonBmpStripped(String input) { 
    if(input == null) throw new IllegalArgumentException("input"); 
    return input.replaceAll("[^\\u0000-\\uFFFF]", ""); 
} 

あなたはBMPを超えてサポートしたい場合は、MySQLを必要5.5+、あなたはだ、すべてを変更する必要がありますutf8utf8mb4(照合、文字セットなど)。しかし、あなたはまた私が に慣れていないことを、ドライバーでこれをサポートする必要があります。これらの文字をJavaで処理することは、2つ以上に広がっているため、痛みです。chars したがって、多くの操作で特別な処理が必要です。

+0

正規表現がコードポイントのレベルで評価され、コードユニットでは評価されないため、実際にはうまくいきません。あなたは\ u0000- \ uFFFF(私の答えを見てください)の範囲外の文字と一致する必要があります。 – verglor

+0

@ jako512これは他のすべてがコード単位を扱うので驚くべきことです:私は完全なnonBMP文字で動作するよう編集しましたが、元のバージョンの意図は対になっていないサロゲートも削除することでした。 – Esailija

+0

REGEXはあなたの言語。 PHPの場合、 'preg_replace( '/ [^ \ x {0000} - \ x {FFFF}]/u'、 '\ x {FFFD}'、$ input);' – DOOManiac

3

I foundは以下であるJavaで非BMPのcharactresを除去するための最良のアプローチ:

inputString.replaceAll("[^\\u0000-\\uFFFF]", "\uFFFD"); 
関連する問題