找出 Java/Android 中 UTF-8 字符串中的字符数
Find out number of characters in a UTF-8 string in Java/Android
当字符串以 UTF-8 格式存储时,我试图找出字符串长度。
我尝试了以下方法:
String str = "मेरा नाम";
Charset UTF8_CHARSET = Charset.forName("UTF-8");
byte[] abc = str.getBytes(UTF8_CHARSET);
int length = abc.length;
这给出了字节数组的长度,但不是字符串中的字符数。
我找到了一个同时显示 UTF-8 字符串长度和字节长度的网站。
https://mothereff.in/byte-counter
假设我的字符串是 मेरा नाम,那么我应该将字符串长度设置为 8 个字符而不是 22 个字节。
谁能指导一下。
只需将程序保存为 utf-8
并按以下步骤进行
String str= "मेरा नाम";
System.out.println(str.length());
o/p = 8
无需将 password[0]
转换为字节数组,您只需 运行
password[0].length();
您还可以将 bytearray 转换回字符串,然后 运行 在其上使用 lenght 方法。
byte[] abc = password[0].getBytes(UTF8_CHARSET);
String s1 = new String(abc, "UTF-8");
System.out.println(s1.length());
String.length()
实际上 returns 以 UTF-16 编码的字符串中的字符数(其中两个字节用于对字符进行编码)。然而,这也适用于大多数 UTF-8 字符,除非你有一个 ASCII 值大于 127 的字符。如果你想手动做事而不将其编码为 UTF-8,你可以这样做
public static int utf8Length(CharSequence sequence) {
int count = 0;
for (int i = 0; i < sequence.length(); i++) {
char ch = sequence.charAt(i);
if (ch <= 0x7F) {
count++;
} else if (ch <= 0x7FF) {
count += 2;
} else if (Character.isHighSurrogate(ch)) {
count += 4;
++i;
} else {
count += 3;
}
}
return count;
}
这是UTF-8 spec。
看看http://rosettacode.org/wiki/String_length#Grapheme_Length_4:
import java.text.BreakIterator;
public class Grapheme {
public static void main(String[] args) {
printLength("møøse");
printLength("");
printLength("J̲o̲s̲é̲");
}
public static void printLength(String s) {
BreakIterator it = BreakIterator.getCharacterInstance();
it.setText(s);
int count = 0;
while (it.next() != BreakIterator.DONE) {
count++;
}
System.out.println("Grapheme length: " + count+ " " + s);
}
}
输出:
Grapheme length: 5 møøse
Grapheme length: 7
Grapheme length: 4 J̲o̲s̲é̲
您要查找的不是字符串长度而是葡萄长度。它为您提供了 "visible" 个字符的数量。
最短的 "length" 是 Unicode 代码点,作为编号字符的概念,UTF-32。
更正:
正如@liudongmiao 提到的,可能应该使用:
int length = string.codePointCount(0, s.length);
在java 8:
int length = (int) string.codePoints().count();
前 java秒:
int length(String s) {
int n = 0;
for (int i = 0; i < s.length(); ++n) {
int cp = s.codePointAt(i);
i += Character.charCount(cp);
}
return n;
}
一个 Unicode 代码点可以用 UTF-16 编码为一个或两个 char
。
同一个 Unicode 字符可能有变音符号。它们可以写成单独的代码点:基本字母 + 零个或多个变音符号。将字符串规范化为一个 (C=) 压缩代码点:
string = java.text.Normalizer.normalize(string, Normalizer.Form.NFC);
顺便说一句,对于数据库而言,UTF-16 长度似乎更有用:
string.length() // Number of UTF-16 chars, every char two bytes.
(例子中提到的UTF-32长度==UTF-16长度。)
转储功能
评论者有一些意想不到的结果:
void dump(String s) {
int n = 0;
for (int i = 0; i < s.length(); ++n) {
int cp = s.codePointAt(i);
int bytes = Character.charCount(cp);
i += bytes;
System.out.printf("[%d] #%dB: U+%X = %s%n",
n, bytes, cp, Character.getName(cp));
}
System.out.printf("Length:%d%n", n);
}
UTF-8 String.length() returns 个字符。]
例如:
String str = "安德鲁真的很棒";
System.out.println(str.length()); //显示16对应16个字符
System.out.println(str.getBytes().length); //显示48对应48字节
当字符串以 UTF-8 格式存储时,我试图找出字符串长度。 我尝试了以下方法:
String str = "मेरा नाम";
Charset UTF8_CHARSET = Charset.forName("UTF-8");
byte[] abc = str.getBytes(UTF8_CHARSET);
int length = abc.length;
这给出了字节数组的长度,但不是字符串中的字符数。
我找到了一个同时显示 UTF-8 字符串长度和字节长度的网站。 https://mothereff.in/byte-counter 假设我的字符串是 मेरा नाम,那么我应该将字符串长度设置为 8 个字符而不是 22 个字节。
谁能指导一下。
只需将程序保存为 utf-8
并按以下步骤进行
String str= "मेरा नाम";
System.out.println(str.length());
o/p = 8
无需将 password[0]
转换为字节数组,您只需 运行
password[0].length();
您还可以将 bytearray 转换回字符串,然后 运行 在其上使用 lenght 方法。
byte[] abc = password[0].getBytes(UTF8_CHARSET);
String s1 = new String(abc, "UTF-8");
System.out.println(s1.length());
String.length()
实际上 returns 以 UTF-16 编码的字符串中的字符数(其中两个字节用于对字符进行编码)。然而,这也适用于大多数 UTF-8 字符,除非你有一个 ASCII 值大于 127 的字符。如果你想手动做事而不将其编码为 UTF-8,你可以这样做
public static int utf8Length(CharSequence sequence) {
int count = 0;
for (int i = 0; i < sequence.length(); i++) {
char ch = sequence.charAt(i);
if (ch <= 0x7F) {
count++;
} else if (ch <= 0x7FF) {
count += 2;
} else if (Character.isHighSurrogate(ch)) {
count += 4;
++i;
} else {
count += 3;
}
}
return count;
}
这是UTF-8 spec。
看看http://rosettacode.org/wiki/String_length#Grapheme_Length_4:
import java.text.BreakIterator;
public class Grapheme {
public static void main(String[] args) {
printLength("møøse");
printLength("");
printLength("J̲o̲s̲é̲");
}
public static void printLength(String s) {
BreakIterator it = BreakIterator.getCharacterInstance();
it.setText(s);
int count = 0;
while (it.next() != BreakIterator.DONE) {
count++;
}
System.out.println("Grapheme length: " + count+ " " + s);
}
}
输出:
Grapheme length: 5 møøse
Grapheme length: 7
Grapheme length: 4 J̲o̲s̲é̲
您要查找的不是字符串长度而是葡萄长度。它为您提供了 "visible" 个字符的数量。
最短的 "length" 是 Unicode 代码点,作为编号字符的概念,UTF-32。
更正: 正如@liudongmiao 提到的,可能应该使用:
int length = string.codePointCount(0, s.length);
在java 8:
int length = (int) string.codePoints().count();
前 java秒:
int length(String s) {
int n = 0;
for (int i = 0; i < s.length(); ++n) {
int cp = s.codePointAt(i);
i += Character.charCount(cp);
}
return n;
}
一个 Unicode 代码点可以用 UTF-16 编码为一个或两个 char
。
同一个 Unicode 字符可能有变音符号。它们可以写成单独的代码点:基本字母 + 零个或多个变音符号。将字符串规范化为一个 (C=) 压缩代码点:
string = java.text.Normalizer.normalize(string, Normalizer.Form.NFC);
顺便说一句,对于数据库而言,UTF-16 长度似乎更有用:
string.length() // Number of UTF-16 chars, every char two bytes.
(例子中提到的UTF-32长度==UTF-16长度。)
转储功能
评论者有一些意想不到的结果:
void dump(String s) {
int n = 0;
for (int i = 0; i < s.length(); ++n) {
int cp = s.codePointAt(i);
int bytes = Character.charCount(cp);
i += bytes;
System.out.printf("[%d] #%dB: U+%X = %s%n",
n, bytes, cp, Character.getName(cp));
}
System.out.printf("Length:%d%n", n);
}
UTF-8 String.length() returns 个字符。]
例如:
String str = "安德鲁真的很棒";
System.out.println(str.length()); //显示16对应16个字符 System.out.println(str.getBytes().length); //显示48对应48字节