私はのドキュメントStringBuffer
、特にreverse()メソッドを読んでいました。そのドキュメントは、サロゲートペアについて何かを述べています。このコンテキストでサロゲートペアとは何ですか?そして、低および高代理は何ですか?
String
。Javaが悪すぎると、OOを使用してそれを修正することはできませんが、String
クラスとクラスの両方StringBuffer
がfinal
拡張されています。殺されたというのは、それは婉曲表現ではないでしょうか。:)
私はのドキュメントStringBuffer
、特にreverse()メソッドを読んでいました。そのドキュメントは、サロゲートペアについて何かを述べています。このコンテキストでサロゲートペアとは何ですか?そして、低および高代理は何ですか?
String
。Javaが悪すぎると、OOを使用してそれを修正することはできませんが、String
クラスとクラスの両方StringBuffer
がfinal
拡張されています。殺されたというのは、それは婉曲表現ではないでしょうか。:)
回答:
「サロゲートペア」という用語は、UTF-16エンコードスキームで高コードポイントでUnicode文字をエンコードする手段を指します。
Unicode文字エンコーディングでは、文字は0x0〜0x10FFFFの値にマッピングされます。
内部的には、JavaはUTF-16エンコードスキームを使用してUnicodeテキストの文字列を格納します。UTF-16では、16ビット(2バイト)コード単位が使用されます。16ビットには0x0から0xFFFFまでの文字の範囲しか含めることができないため、この範囲(0x10000から0x10FFFF)を超える値を格納するために、さらに複雑さが使用されます。これは、サロゲートと呼ばれるコード単位のペアを使用して行われます。
サロゲートコードユニットは、2つのコードユニットシーケンスの先頭または末尾で許可されているかどうかに応じて、「高サロゲート」および「低サロゲート」と呼ばれる2つの範囲にあります。
初期のJavaバージョンは、16ビットcharデータ型を使用してUnicode文字を表していました。すべてのUnicode文字が65,535(0xFFFF)未満の値を持ち、16ビットで表現できるため、この設計は当時は意味がありました。しかし、その後、Unicodeは最大値を1,114,111(0x10FFFF)に増やしました。16ビット値は小さすぎてUnicodeバージョン3.1のすべてのUnicode文字を表すことができないため、32ビット値(コードポイントと呼ばれる)がUTF-32エンコードスキームに採用されました。ただし、メモリを効率的に使用するには、16ビット値が32ビット値よりも優先されるため、Unicodeは、16ビット値の継続的な使用を可能にする新しい設計を導入しました。この設計は、UTF-16エンコードスキームで採用されており、1,024個の値を16ビットの上位サロゲート(U + D800からU + DBFFの範囲内)に割り当て、別の1,024個の値を16ビットの下位サロゲート(U + DC00の範囲内)に割り当てます。 U + DFFFへ)。
そのドキュメントが言っていることは、無効なUTF-16文字列reverse
は有効な文字列の逆になる可能性があるため、メソッドを呼び出した後に有効になる可能性があるということです。サロゲートペア(ここで説明)は、単一のUnicodeコードポイントをエンコードするUTF-16の16ビット値のペアです。低サロゲートと高サロゲートは、そのエンコーディングの2つの半分です。
この投稿の上記の回答にいくつかの情報を追加しています。
Java-12でテスト済み、5より上のすべてのJavaバージョンで動作するはずです。
ここで述べたように:https : //stackoverflow.com/a/47505451/2987755、
どちらの文字(UnicodeがU + FFFFを超える)も、Javaがchar値のペアとして格納するサロゲートペア、つまり単一のUnicodeとして表されます文字は、隣接する2つのJava文字として表されます。
次の例でわかるように。
1.長さ:
"🌉".length() //2, Expectations was it should return 1
"🌉".codePointCount(0,"🌉".length()) //1, To get the number of Unicode characters in a Java String
2.等価性:以下のように
Unicode \ud83c\udf09
を使用して文字列に「🌉」を表し、等価性を確認します。
"🌉".equals("\ud83c\udf09") // true
JavaはUTF-32をサポートしていません
"🌉".equals("\u1F309") // false
3. Unicode文字をJava文字列に変換できます
"🌉".equals(new String(Character.toChars(0x0001F309))) //true
4. String.substring()は補助文字を考慮しません
"🌉🌐".substring(0,1) //"?"
"🌉🌐".substring(0,2) //"🌉"
"🌉🌐".substring(0,4) //"🌉🌐"
これを解決するために使用できます String.offsetByCodePoints(int index, int codePointOffset)
"🌉🌐".substring(0,"🌉🌐".offsetByCodePoints(0,1) // "🌉"
"🌉🌐".substring(2,"🌉🌐".offsetByCodePoints(1,2)) // "🌐"
5.反復処理Unicode文字列のBreakIterator
ユニコード6.ソートストリングjava.text.Collator
7キャラクタのtoUpperCase()
、toLowerCase()
特定のロケールの、方法が使用されるべきではなく、代わりに、使用文字列大文字と小文字。
8. Character.isLetter(char ch)
はサポートされていませんが、よく使用されます。CharacterクラスのメソッドCharacter.isLetter(int codePoint)
ごとmethodName(char ch)
に、methodName(int codePoint)
補助文字を処理できるタイプがあります。
9.で文字セットを指定しString.getBytes()
、バイトから文字列に変換しInputStreamReader
、OutputStreamWriter
参照:https :
//coolsymbol.com/emojis/emoji-for-copy-and-paste.html#objects
https://www.online-toolz.com/tools/text-unicode-entities-convertor.php
https: //www.ibm.com/developerworks/library/j-unicode/index.html
https://www.oracle.com/technetwork/articles/javaee/supplementary-142654.html
サロゲートペアは、特定の文字をエンコードするUTF-16の方法を参照します。http://en.wikipedia.org/wiki/UTF-16/UCS-2#Code_points_U.2B10000..U.2B10FFFFを参照してください
小さな序文
バージョン3.1以前は、主に使用されていたのは、UTF-8と呼ばれる8ビットのエンコードと、UCS-2または「2オクテットでコード化されたユニバーサル文字セット」と呼ばれる16ビットエンコーディングでした。UTF-8はUnicodeポイントを1バイトブロックのシーケンスとしてエンコードしますが、UCS-2は常に2バイトを使用します。
A = 41 -UTF-8の8ビットの1ブロック
A = 0041 -UCS-2の16ビットの1ブロック
Ω= CE A9 -UTF-8の8ビットの2ブロック
Ω= 03A9-の 1ブロックUCS-2の16ビット
問題
コンソーシアムは、人間が読める言語をすべてカバーするには16ビットで十分であると考えました。これにより、2 ^ 16 = 65536の可能なコード値が得られます。これは、BPMまたはBasic Multilingual Planeとしても知られるPlane 0にも当てはまり、現在、65536個のコードポイントのうち55,445個が含まれています。BPMは、中日韓記号(CJK)を含め、世界中のほぼすべての人間の言語をカバーしています。
時間の経過と新しいアジアの文字セットが追加され、中国のシンボルだけで70,000ポイント以上を獲得しました。現在、標準のpartの一部として絵文字ポイントさえあります。新しい16個の「追加」プレーンが追加されました。UCS-2ルームは、Plane-0より大きなものをカバーするには十分ではありませんでした。
Unicodeの決定
UCS-2に基づいてUTF-16を作成します。UTF-16を動的にすることで、ポイントあたり2バイトまたは4バイトがかかります。1024ポイントU + D800–U + DBFF(High Surrogatesと呼ばれる)をUTF-16に割り当てます。1024個のシンボルU + DC00–U + DFFF(Low Surrogatesと呼ばれる)をUTF-16に割り当てます。
これらの変更により、BPMはUTF-16の16ビットの1ブロックでカバーされますが、すべての「補足文字」は、それぞれ16ビットで2ブロックを示すサロゲートペアでカバーされ、合計1024x1024 = 1 048 576ポイントになります。
高いサロゲートが低いサロゲートに先行します。このルールからの逸脱は、不適切なエンコーディングと見なされます。たとえば、ペアのないサロゲートは正しくありません。高サロゲートの前にある低サロゲートは正しくありません。
M、「MUSICAL SYMBOL G CLEF」は、サロゲートのペアとして0xD834 0xDD1E(2 x 2バイト)、
UTF-8として0xF0 0x9D 0x84 0x9E(4 x 1バイト)、
UTF-32としてUTF-16でエンコードされます0x0001D11E(1 x 4バイト)。
現在の状況
トピックdetailsに従うために、多くの歴史的詳細が抑制されました。
最新のUnicode標準は、http://www.unicode.org/versions/latestにあります。
サロゲートペアは、UTF-16の2つの「コード単位」であり、1つの「コードポイント」を構成します。Javaのドキュメントでは、これらの「コードポイント」は引き続き有効であり、「コード単位」は逆の順序で正しく並べられていると述べています。さらに、ペアになっていない2つのサロゲートコードユニットを逆にして、有効なサロゲートペアを形成できると述べています。つまり、ペアになっていないコードユニットがある場合、逆の逆が同じではない可能性があります。
ただし、ドキュメントには、複数のコードポイントを組み合わせたGraphemesについては何も記載されていません。つまり、eとそれに伴うアクセントがまだ切り替えられている可能性があるため、eの前にアクセントを配置します。つまり、eの前に別の母音がある場合、eにあったアクセントが得られる可能性があります。
うわぁ!