は私のデータベースでは、私は4バイトを知っているようにUnicodeは法的私のJavaがあるエラーチェックUTF-8データ型の3バイト、または4バイトのUnicode
私は、JavaとMySQL 5を使用して、取得しますMySQL 5では違法ですが、問題が発生する可能性があり、データのタイプをチェックしたいと思います。 UTF-8データが3バイトまたは4バイトのUnicodeであることを確認するにはどうすればよいですか?
は私のデータベースでは、私は4バイトを知っているようにUnicodeは法的私のJavaがあるエラーチェックUTF-8データ型の3バイト、または4バイトのUnicode
私は、JavaとMySQL 5を使用して、取得しますMySQL 5では違法ですが、問題が発生する可能性があり、データのタイプをチェックしたいと思います。 UTF-8データが3バイトまたは4バイトのUnicodeであることを確認するにはどうすればよいですか?
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;
}
あなたはあなただけのMySQLにそれを渡す前に、それらの文字を削除することができ、BMPを超えてサポートしたくない場合は、次の
public static String withNonBmpStripped(String input) {
if(input == null) throw new IllegalArgumentException("input");
return input.replaceAll("[^\\u0000-\\uFFFF]", "");
}
あなたはBMPを超えてサポートしたい場合は、MySQLを必要5.5+、あなたはだ、すべてを変更する必要がありますutf8
〜utf8mb4
(照合、文字セットなど)。しかし、あなたはまた私が に慣れていないことを、ドライバーでこれをサポートする必要があります。これらの文字をJavaで処理することは、2つ以上に広がっているため、痛みです。chars
したがって、多くの操作で特別な処理が必要です。
正規表現がコードポイントのレベルで評価され、コードユニットでは評価されないため、実際にはうまくいきません。あなたは\ u0000- \ uFFFF(私の答えを見てください)の範囲外の文字と一致する必要があります。 – verglor
@ jako512これは他のすべてがコード単位を扱うので驚くべきことです:私は完全なnonBMP文字で動作するよう編集しましたが、元のバージョンの意図は対になっていないサロゲートも削除することでした。 – Esailija
REGEXはあなたの言語。 PHPの場合、 'preg_replace( '/ [^ \ x {0000} - \ x {FFFF}]/u'、 '\ x {FFFD}'、$ input);' – DOOManiac
I foundは以下であるJavaで非BMPのcharactresを除去するための最良のアプローチ:
inputString.replaceAll("[^\\u0000-\\uFFFF]", "\uFFFD");
私はあなたの列のデータ・タイプの長さの制限、あなたが最初に挿入しようとしているデータのサイズを見てお勧めします。 'VARCHAR'に100K文字を挿入している場合は、エンコーディングに誤りはありません。 – Jon
4バイトのUTF-8エンコードされた文字がこの問題の原因だとは思わない。 UTF-8エンコード時に* m *バイト(* m *> * n *)を使用するが、VARCHAR(* n *)に入れる必要がある* n *文字列が原因である可能性が高くなります。 –
@Jonまず最初にチェックしたが、それは問題ではなかったが、私はすでに解決していたが、今後もエンコーディングのチェックを使うつもりだと思う。 – akuzma