Ten okazuje się być naprawdę brzydkie .... Mam debugowany kryteria wyszukiwania i zawiera następujące znaki (i ich pozycję hex):
க 0x0b95
ு 0x0bc1
ம 0x0bae
ா 0x0bbe
ர 0x0bb0
் 0x0bcd
Tak język tamilski oczywiście użyć diacritics-like sekwencje, aby uzyskać wszystkie znaki, które niestety liczą się jako oddzielne jednostki.
To nie jest problem z UTF-8/UTF-16 jako błędnie zgłaszane przez innych odpowiedzi, jest nieodłącznym kodowaniem Unicode języka Tamil .
Zasugerowany Normalizer nie działa, wydaje się, że tamil ma został zaprojektowany przez "ekspertów" Unicode, aby jawnie używać kombinacji sekwencji, których nie można znormalizować. Aargh.
Mój następny pomysł jest nie do policzenia znaki, ale glify Visual reprezentacje znaków.
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());
Rezultatem
க 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]
Jako gl yphs przecinają się, musisz użyć funkcji typu Java funkcji jak w innym rozwiązaniu.
ROZWIĄZANIE:
Używam tego linku: 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;
}
Trzeba wykluczyć znaki kombinowane i policzyć je odpowiednio.
To nie ma żadnego znaczenia dla tego problemu, ale nie ma potrzeby korzystania z 'new String („...”)', po prostu wykonaj: 'String str1 =" குமார் ";' – Jesper
Zobacz artykuł http://www.venkatarangan.com/blog/content/binary/Counting%20Letters%20in%20an%20Unicode%20String.pdf, aby zapoznać się z artykułem dotyczącym tego problemu. – halex
Blog jest naprawdę bardzo pouczający. Ale nie daje nam opcji w java, aby podzielić ciąg na trzy znaczące znaki. – user1611248