これは本当に醜いことが判明しました....あなたの文字列をデバッグしましたが、次の文字(およびそれらの16進位置)が含まれています:
க 0x0b95
ு 0x0bc1
ம 0x0bae
ா
0x0bbe ர 0x0bb0 ்
0x0bcd
そのため、タミル語は明らかに分音記号のようなシーケンスを使用して、残念ながら個別のエンティティとしてカウントされるすべての文字を取得します。
これは、他の回答で誤って主張されているように、UTF-8 / UTF-16 の問題ではなく、タミル語の Unicode エンコーディングに固有のものです。
提案されたノーマライザーは機能しません。タミル語は Unicode の「専門家」によって、正規化できない組み合わせシーケンスを明示的に使用するように設計されているようです。ああ。
私の次のアイデアは、文字を数えるのではなく、文字の視覚的表現であるグリフを数えることです。
String str1 = new String(Normalizer.normalize("குமார்", Normalizer.Form.NFC ));
Font display = new Font("SansSerif",Font.PLAIN,12);
GlyphVector vec = display.createGlyphVector(new FontRenderContext(new AffineTransform(),false, false),str1);
System.out.println(vec.getNumGlyphs());
for (int i=0; i<str1.length(); i++)
System.out.printf("%s %s %s %n",str1.charAt(i),Integer.toHexString((int) str1.charAt(i)),vec.getGlyphVisualBounds(i).getBounds2D().toString());
結果:
க b95 [x=0.0,y=-6.0,w=7.0,h=6.0]
ு bc1 [x=8.0,y=-6.0,w=7.0,h=4.0]
ம bae [x=17.0,y=- 6.0,w=6.0,h =6.0] → bbe [x
=23.0,y=-6.0,w=5.0,h=6.0]
→ bb0 [x=30.0,y=-6.0,w=4.0,h=8.0]
் bcd [x=31.0,y=-9.0,w=1.0,h=2.0]
グリフが交差しているため、他のソリューションのように Java 文字型関数を使用する必要があります。
解決:
私はこのリンクを使用しています: http://www.venkatarangan.com/blog/content/binary/Counting%20Letters%20in%20an%20Unicode%20String.pdf
public static int getTamilStringLength(String tamil) {
int dependentCharacterLength = 0;
for (int index = 0; index < tamil.length(); index++) {
char code = tamil.charAt(index);
if (code == 0xB82)
dependentCharacterLength++;
else if (code >= 0x0BBE && code <= 0x0BC8)
dependentCharacterLength++;
else if (code >= 0x0BCA && code <= 0x0BD7)
dependentCharacterLength++;
}
return tamil.length() - dependentCharacterLength;
}
組み合わせ文字を除外し、それに応じて数える必要があります。