6

Unicode ポイントが有効かどうかを示すことができるアルゴリズムまたはライブラリが必要です。たとえばU+F8F8、有効な Unicode 文字ではないように見えますが、"PRIVATE_USE_AREA". 私はICUを見つけました - これは良い/最善の解決策ですか?

更新: @Reprogrammer の提案 (以下) を使用することです。

CoderResult call(CharsetDecoderICU decoder, Object context, 
     ByteBuffer source, CharBuffer target, IntBuffer offsets, 
     char[] buffer, int length, CoderResult cr)
This function is called when the bytes in the source cannot be handled, 
    and this function is meant to handle or fix the error if possible.

ありがとう。これは私が望んでいたよりも複雑に見えます - おそらくそれは私が思っていたよりも複雑な問題なのかもしれません. (問題には'<Non Private Use High Surrogate, First>' (U+D800)、少なくとも 1 つ以上のコード ポイントが続く場合にのみ有効である (と私が推測する) などのポイントが含まれます。

更新: @Jukka は次のように書いています。

「有効」を定義します。Private Use コード ポイントは Unicode 標準に従って有効ですが、標準で割り当てられた文字がありません。サロゲート コード ポイントは有効な文字データではありませんが、サロゲート コード単位は UTF-16 で使用できます。Java 文字列は、文字ではなく一連のコード単位です。そこには任意のコード単位が表示されますが、文字列を文字として処理する場合は、文字に関する Unicode 要件に準拠する必要があります。– ユッカ・K・コルペラ

「有効」を定義することが重要であることに同意します。私は次のように宣言したFileFormat.Infoサイトから使用法を取得しました。

 U+F8F8 is not a valid unicode character.

かなり権威のあるサイトのようですので、その用語を使用しました。多分彼らはやや不正確です

更新: @Ignacio の Python を Java にしようとしましたが、失敗しました。私が書いた

public void testUnicode() {
        Pattern pattern = Pattern.compile("\\p{Cn}");
        System.out.println("\\u0020 "+pattern.matcher("\u0020").matches());
        System.out.println("A "+pattern.matcher("A").matches());
        System.out.println("\\uf8f8 "+pattern.matcher("\uf8f8").matches());
    }

「有効な」Unicode文字であっても、一様にfalseを返しました。文書化されたものも見つかりませんでし\p{Cn}た。

4

3 に答える 3

5

@IgnacioVazquez-Abramsによる回答へのコメントで説明するアプローチは"\\p{Cn}"、General Category(gc)プロパティをテストするのようなパターンとのマッチングを使用した正しいアプローチです。ただし、U + F8F8の場合、このキャラクターのカテゴリはCnではなくCs(その他、代理)であるため、この特定の一致は正しくfalseになります。たとえばU+FFFFをテストすると、真になります。

メジャークラスC(カテゴリ名がCで始まる)のUnicodeカテゴリは次のとおりです。

  • Cc:その他、コントロール; 制御文字、例:キャリッジリターン
  • Cf:その他、フォーマット; 例:ソフトハイフン(非表示ですが、フォーマットに影響する可能性があります)
  • Cs:その他、代理人。文字データでは無効ですが、Java文字列(文字ではなくコード単位の文字列)にペアで表示される場合があります
  • Co:その他の私的使用。文字データでは有効ですが、Unicode標準によって文字が割り当てられていないため、(コードポイントに何らかの意味を割り当てる)プライベート割り当て以外の情報交換では使用しないでください。
  • Cn:その他、割り当てられていません。これは、コードポイントが文字以外として永続的に示されているか、割り当てられていない、たとえばまだ割り当てられていないことを意味する場合があります(ただし、Unicodeの将来のバージョンでは文字に割り当てられる可能性があります)

したがって、有効性をテストするときは、Cnを拒否する必要があります(Unicode標準が変更されたときに有効な文字が拒否される可能性があることを考慮して)。コードポイントをテストするときはCsを拒否する必要がありますが、Java文字列を処理するときは、最初の文字が高サロゲートで2番目の文字が低サロゲートのときにCs文字のペアを受け入れる必要があります(基本多言語面を超える文字を受け入れることを前提としています)。 ); Coの処理は、私的使用のコードポイントを有効として扱うかどうかによって異なります。

プライベートユースのコードポイントは、たとえば、そのようなコードポイントにグリフが割り当てられているフォントを使用して表示することを目的としたデータに表示される場合があります。そのようなフォントは扱いにくいですが、存在し、アプローチは形式的に正しくありません。

他の主要なクラスのUnicodeコードポイントは、疑いの余地のない文字として扱われます。これは、アプリケーションがそれらを受け入れる必要があることを意味するのではなく、それらが文字を有効に示していることを意味します。

于 2012-12-12T04:48:49.440 に答える
1

String.codePointAtを使用してみてください
APIは次のとおりです。

int java.lang.String.codePointAt(int index)



codePointAt
public int codePointAt(int index)
Returns the character (Unicode code point) at the specified index. 
   The index refers to char values (Unicode code units) and ranges from 0 to length() - 1. 
If the char value specified at the given index is in the high-surrogate range, the 
    following index is less than the length of this String, and the char value at the 
    following index is in the low-surrogate range, then the supplementary code point 
    corresponding to this surrogate pair is returned. Otherwise, the char value at the
    given index is returned. 


Parameters:
index - the index to the char values 
Returns:
the code point value of the character at the index 
Throws: 
IndexOutOfBoundsException - if the index argument is negative or not less than the 
    length of this string.
于 2012-12-10T06:36:36.713 に答える
0

「Cn」Unicode プロパティへの一致は、無効な Unicode 文字を示します。Python での例 (Java に簡単に変換できます):

>>> regex.match(r'\p{Cn}', u'\ud800')
<_regex.Match object at 0x7f6d5552c120>
>>> regex.match(r'\p{Cn}', u'a')
>>> regex.match(r'\p{Cn}', u'\uf8f8')
<_regex.Match object at 0x7f6d5552c198>
于 2012-12-10T06:06:46.797 に答える