如何获取 Unicode 字符的编码?

70

假设我有这样一个代码:

char registered = '®';

umlaut,或任何 Unicode 字符。我如何获取它的代码?

7个回答

118

将其转换为int即可:

char registered = '®';
int code = (int) registered;
实际上,从char到int有一个隐式转换,所以你不必像我上面那样明确指定它,但在这种情况下,我建议这样做,以便清楚明了你的意图。
这将给出UTF-16代码单元 - 对于任何定义在基本多语言平面中的字符来说,它与Unicode代码点相同。(Java中只有BMP字符可以用char值表示)正如Andrzej Doyle的答案所说,如果要从任意字符串获取Unicode代码点,请使用Character.codePointAt()。
一旦获得了UTF-16代码单元或Unicode代码点(两者都是整数),你可以自由选择怎么处理它们。如果你想要一个字符串表示,你需要决定你想要什么样的表示方式。(例如,如果你知道该值始终在BMP中,你可能希望使用固定的4位十六进制表示法,并在前面加上"U+",例如空格的表示为"U+0020")但我们不知道需求,这已超出了这个问题的范围。

3
可以翻译为:“在基本多语言平面上的任何字符都可以,但是Java中的单个字符无法表示U+FFFF以上的字符。不过,在实际定义中,一个字符被定义为UTF-16编码点。” - Jon Skeet
10
它适用于所有表示Unicode字符的char,编码在U+FFFF以下,但并非所有Unicode字符都适用,因为char无法表示所有Unicode字符。根据您使用的char源,您可能需要进行更复杂的操作(并且确实应该为此做好准备)。 - JaakkoK
5
要将其转换为十六进制,请使用Integer#toHexString() - BalusC
1
如果它在基本多语言平面之外怎么办? - fzzfzzfzz
1
@fzzfzzfzz:那么你就不需要将它作为单个char开始,而是可以使用char.Convert.ToUtf32 - Jon Skeet
显示剩余4条评论

43

一种更完整但冗长的方法是使用Character.codePointAt方法。该方法可以处理“高代理项”字符,这些字符不能由单个整数表示,而是需要多个char表示。

在您提供的示例中,这并非必需 - 如果(Unicode)字符可以容纳在单个(Java)char中(例如registered局部变量),那么它必须落在\u0000\uffff范围内,您就不需要担心代理对了。但如果您正在查看来自String/char数组的可能更高代码点,则调用此方法是明智的,以便涵盖边缘情况。

例如,不要使用以下方式:

String input = ...;
char fifthChar = input.charAt(4);
int codePoint = (int)fifthChar;

使用

String input = ...;
int codePoint = Character.codePointAt(input, 4);

这不仅在此情况下减少了一些代码,而且它会为您处理代理对的检测。


2
另外,在String类中也有相同的方法,String#codePointAt - mosov.a

11

在Java中,char本质上是一个"16位整数",所以您可以将其直接强制转换为int类型,这样就可以得到它的代码。

引用自Oracle

char数据类型是单个16位Unicode字符。 它的最小值为'\u0000'(或0),最大值为'\uffff'(或65,535,包括)。

因此您可以将其直接转换为int类型。

char registered = '®';
System.out.println(String.format("This is an int-code: %d", (int) registered));
System.out.println(String.format("And this is an hexa code: %x", (int) registered));

1
它甚至可以处理欧元符号 String.format("%x", (int) '€') == 0x20ac == '\u20ac' - ATorras

1

有一个开源库MgntUtils,其中有一个实用类StringUnicodeEncoderDecoder。该类提供了将任何字符串转换为Unicode序列的静态方法,非常简单和有用。要转换字符串,只需执行以下操作:

String codes = StringUnicodeEncoderDecoder.encodeStringToUnicodeSequence(myString);

例如,一个字符串"Hello World"将被转换为"\u0048\u0065\u006c\u006c\u006f\u0020\u0057\u006f\u0072\u006c\u0064"。它适用于任何语言。这是一篇文章的链接,讲解了库的所有细节: MgntUtils。查找子标题"String Unicode converter"。该库可以作为Maven artifact获取,也可以从Github获取(包括源代码和Javadoc)。

1
对我而言,只有"Integer.toHexString(registered)"才按照我期望的方式起作用:
char registered = '®';
System.out.println("Answer:"+Integer.toHexString(registered));

这个答案只会给你通常在表格中呈现的字符串表示。Jon Skeet的回答解释得更多。


2
正如我回答中的评论所指出的那样,这是因为“你想要的方式”是生成代码的十六进制表示形式 - 这不是这个问题所要求的。代码本身是一个整数;“如何创建整数的十六进制表示形式”是另一回事。(对于Unicode代码点,您还应考虑要使用多少个十六进制数字 - 您可能希望对BMP字符使用4个数字,对其他字符使用6个数字,或始终使用6个数字或始终使用偶数数字,例如...) - Jon Skeet
这表明了你所写的观点。是什么让你认为代码本质上是整数呢?对我而言,代码是符号的组合,不一定是数字或整数。你的回答非常有用,但最终我花了半个小时才找到如何获取我理解的代码,也许这会节省其他用户一些免费时间。 - Darius Miliauskas

0
亲爱的朋友,Jon Skeet说你可以找到字符的十进制代码,但它不是Unicode中应该提到的字符十六进制代码,因此你应该通过HexCode来表示字符代码,而不是十进制。
有一个开源工具http://unicode.codeplex.com提供有关字符或句子的完整信息。
因此最好创建一个解析器,将字符作为参数并返回一个十六进制代码字符串。
public static String GetHexCode(char character)
    {
        return String.format("{0:X4}", GetDecimal(character));
    }//end

希望它有所帮助

1
因此,您应该使用十六进制代码表示字符代码,而不是十进制。只有在将其转换为字符串时,才涉及到十六进制与十进制的区别,在问题中根本没有这样的要求。 - Jon Skeet
1
你认为发布一个C#链接并附上一些C#代码,能够帮助解决Java问题吗? - Ferrybig

-2

//以下是获取Unicode的方法

int a = 'a'; // 'a'代表你想要获取其Unicode的字母或符号

//以下是通过Unicode获取字母或符号的方法

System.out.println("\u0123"); //123是你想要转换的Unicode


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