Java:多字节字符串长度

7

我有一个方法,类似Markdown语法,用于在命令行程序中打印"header text"。

1. =======================
2. This is a header string
3. =======================

这个方法使用一个字符c,针对第1和第3行,基于s的长度重复n次。 String.length()对英文字母适用良好,但是如何找到包含外语多字节字符(如“Å”和“Ç”)的字符串的长度(即视觉长度)?

也许你没有以正确的编码读取字符串。 - ReyCharles
2个回答

11

String.length对于那些常见字符是可以的,因为Java字符串使用UTF-16工作,它足以表示大多数常用字符(拉丁文、希腊文、阿拉伯文、希伯来文、中文、泰文、天城体梵文等)。

如果您可能需要处理U+FFFF以上的字符,则需要使用codePointCount而不是length来处理代理对。


如果s是"Ø",那么s.length()会给我一个值为2。但我希望它是1。而且我相信,根据您编译程序时使用的文件编码,您可能会得到不同的值。 - josocblaugrana
@josocblaugrana:我无法确认。我尝试运行了以下程序,它打印了1: public class A { public static void main(String[] args) { System.out.println("Ø".length()); } } - ReyCharles
@ReyCharles:在我的电脑上,运行 System.out.println("Ø".length()) (仅此而已)返回值为 2… 供参考,我使用的是 Mac。 - josocblaugrana
1
@josocblaugrana 很明显,您告诉编译器使用的编码必须与Java源文件的编码匹配,就像在读取文本文件时必须向InputStreamReader传递正确的编码一样。如果您的.java文件是UTF-8编码,但编译器将其读作ISO-8859-1或MacRoman,则会将该字符串文字视为"\u00c3\u0098"而不是"\u00D8" - Ian Roberts
1
如果您不能确定编译器将设置为哪种编码方式,那么您就必须在源代码中使用Unicode转义字符(例如使用 "\u00D8" 而不是 "Ø")。您可以使用 native2ascii 工具来自动化此过程。 - Ian Roberts
显示剩余2条评论

3

String.length()对于大多数Unicode字符,包括ÅÇ都是可以的。

Java字符串采用utf-16编码,其中每个Character占用24字节。

补充字符表示占用4字节的字符,并通过配对两个字符来实现,此时必须使用codePointCount操作而不是length

这些字符肯定存在于标准Unicode规范中。


不,UTF16中每个字符占用2或4个字节。 - Rok Kralj
@RokKralj,这正是我想要表达的。很高兴你发现这不够清楚。 - Johan Sjöberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接