获取字符的unicode值


68

Java中有什么办法可以让我获得与任何字符均等的Unicode?例如

假设有一个方法getUnicode(char c)。呼叫getUnicode('÷')应该返回\u00f7


字符在Java中已经是unicode了。
Mostowski

Answers:


65

您可以使用以下一种衬里对任何Java字符进行处理:

System.out.println( "\\u" + Integer.toHexString('÷' | 0x10000).substring(1) );

但这仅适用于Unicode 3.0以下的Unicode字符,这就是为什么我建议您可以对任何Java字符都使用它。

由于Java是在Unicode 3.1出现之前进行设计的,因此Java的char原语不足以表示Unicode 3.1及更高版本:不再存在“一个Unicode字符到一个Java char”的映射(而是使用了一种怪异的技巧)。

因此,您实际上必须在这里检查您的要求:是否需要支持Java字符或任何可能的Unicode字符?


谢谢。我已经用这种方法检查了所有字符,现在看起来还不错。
萨拉巴2010年

4
“怪胎”是UTF-16,已被广泛使用。它可能并不理想,但是它得到了很好的理解,并且比仅支持UCS-2更好。
Joachim Sauer'2

1
@Joachim:但是,String.charAt现在返回“一半字符”并String.length返回可以与字符数不同的东西是丑陋的,不是吗?(此处的字符表示Unicode代码点,而不是Java字符)String类应该(且在Unicode 3.1之前)独立于编码问题。
Thilo

1
@Joachim:我指的是Thilo所说的。对我来说,真正的问题是要保持向后兼容性,我们有一个方法charAt(...),它不返回字符。那是不好的。方法名称保持不变,但是Javadoc被重写。现在我们有了codePointAt(...),几乎没人知道,而且这个问题非常令人困惑。不是Java的设计者本身的错,因为正如我在回答中所写的那样,Java是在Unicode 3.1出现之前进行设计的。这只是有点伤心,char是16位,而不是32
SyntaxT3rr0r

是的,我知道这一点,这是一个问题。我不否认这一点。但是至少我们有一个很好理解的“修复程序”(或替代方法),而不是陷入整个“噢,不!很多人无法使用ASCII编写语言”问题的相同编码地狱。UTF-16不是理想的,但是它是标准化的并且易于理解。
Joachim Sauer'2

34

如果您有Java 5,请使用 char c = ...; String s = String.format ("\\u%04x", (int)c);

如果您的来源不是Unicode字符(char)而是字符串,则必须使用charAt(index)来将Unicode字符获取到position index

请勿使用,codePointAt(index)因为这将返回24位值(完整Unicode),该值不能仅用4个十六进制数字表示(需要6个数字)。请参阅文档以获取解释

[编辑]要明确:此答案不使用Unicode,而是Java用于表示Unicode字符(即代理对)的方法,因为char是16位,而Unicode是24位。问题应该是:“如何转换char为4位数的十六进制数字”,因为它(并非真的)与Unicode有关。


2
@Aaron Digulla:认为charAt(...)返回Unicode字符是一个常见错误。没有。如果您的String由Unicode 3.0 / BMP字符组成,则charAt(...)仅返回Unicode字符。我不同意他不应该使用codePointAt。他应该使用codePointAt和一种能够对BMP之外的字符进行编码的方法。
语法T3rr0r,2010年

codePointAt会更好,但是如果您确实需要它,那么找出索引的正确值将很棘手。
Thilo

从问题(4位十六进制)开始,很明显Saurabh对真正的Unicode字符并不真正感兴趣(因为它们不适合4位十六进制数字),因此使用codePointAt()将是错误的。
亚伦·迪古拉

@WizardOfOdds:您是否有一个有效的示例,如何获取调用codePointAt所需的索引?
亚伦·迪古拉

@Aaron Digulla:事实是,调用codePointAt(...)时没有索引魔术。codePointAt(...)始终返回Unicode字符,即使它在BMP之外。正是在调用charAt(...)时会遇到麻烦,因为如果在BMP之外的Unicode字符之后调用charAt(...),则不能保证您将读取一个字符。但是也许我误会了你?如果我没记错的话,周围的字符串示例包含音乐笔记(BMP之外的字符)。但是也许我误解了你的问题?
语法T3rr0r,2010年

13
private static String toUnicode(char ch) {
    return String.format("\\u%04x", (int) ch);
}

7
复制3年前的现有答案。
james.garriss 2015年

3
但是,给出的答案要清晰得多,而最好的答案是我的意思。( "\\u" + Integer.toHexString('÷' | 0x10000).substring(1) )
ВсеЕдно18年

“ \\ u” + String.format(“%04x”,(int)c).toUpperCase()
fl0w


1

我在网上找到了这个不错的代码。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Unicode {

public static void main(String[] args) {
System.out.println("Use CTRL+C to quite to program.");

// Create the reader for reading in the text typed in the console. 
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

try {
  String line = null;
  while ((line = bufferedReader.readLine()).length() > 0) {
    for (int index = 0; index < line.length(); index++) {

      // Convert the integer to a hexadecimal code.
      String hexCode = Integer.toHexString(line.codePointAt(index)).toUpperCase();


      // but the it must be a four number value.
      String hexCodeWithAllLeadingZeros = "0000" + hexCode;
      String hexCodeWithLeadingZeros = hexCodeWithAllLeadingZeros.substring(hexCodeWithAllLeadingZeros.length()-4);

      System.out.println("\\u" + hexCodeWithLeadingZeros);
    }

  }
} catch (IOException ioException) {
       ioException.printStackTrace();
  }
 }
}

来源文章


谢谢。你给我我所问的。但是,当我尝试一些俄语字符时,它会返回相同的Unicode值。我认为Unicode值对于不同的字符应该有所不同。我尝试了以下字符-л,и,ц,т,яretuns \ u003F。
萨拉巴2010年

1
我很确定那段代码对于0xFFFF以上的代码点是不正确的。
语法T3rr0r,2010年

1
但是,俄语字符应位于基本多语言平面上(低于0xFFFF)。
Thilo

@Thilo:哦,我知道,我没有评论Saurabh的俄语示例。在发表评论之前,我用我的方法尝试了他的角色,它们工作正常。我只是说我很确定那里的方法不能在BMP之外使用chars。
语法T3rr0r,2010年

2
令人惊讶的是,一个人必须编写多少代码才能解决一个简单的问题。亚伦的解决方案长40个字符。在这里,我们有1124
jarnbjo

0

您是否对使用Unicode感到挑剔,因为使用Java,如果您编写程序以使用“ dec”值或(HTML代码),则更简单,那么您只需在char和int之间转换数据类型

char a = 98;
char b = 'b';
char c = (char) (b+0002);

System.out.println(a);
System.out.println((int)b);
System.out.println((int)c);
System.out.println(c);

提供此输出

b
98
100
d

0

首先,我了解了char的高端。之后,得到低端。转换HexString中的所有内容并放入前缀。

int hs = (int) c  >> 8;
int ls = hs & 0x000F;

String highSide = Integer.toHexString(hs);
String lowSide = Integer.toHexString(ls);
lowSide = Integer.toHexString(hs & 0x00F0);
String hexa = Integer.toHexString( (int) c );

System.out.println(c+" = "+"\\u"+highSide+lowSide+hexa);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.