从数字创建Unicode字符


114

我想在Java中显示Unicode字符。如果我这样做,它就可以正常工作:

String symbol = "\u2202";

符号等于“∂”。这是我想要的。

问题是我知道Unicode号,因此需要从中创建Unicode符号。我(对我)尝试了显而易见的事情:

int c = 2202;
String symbol =  "\\u" + c;

但是,在这种情况下,符号等于“ \ u2202”。那不是我想要的

如果我知道符号的Unicode编号(但只能在运行时-我不能像第一个示例那样对其进行硬编码),如何构造该符号?


1
删除第一个反斜杠,以使它转义Unicode序列,而不是转义反斜杠。使用“ \\”告诉Java您要打印出“ \”,而不是将其用作Unicode字符的转义序列的结尾。如果删除第一个,则它将转义Unicode序列,而不是第二个反斜杠。至少,据我所知。
基金莫妮卡的诉讼案

Answers:


73

只要投你intchar。你可以将其转换成一个String使用Character.toString()

String s = Character.toString((char)c);

编辑:

请记住,Java源代码(\u位)中的转义序列是十六进制的,因此,如果您要重现转义序列,则需要使用int c = 0x2202


3
那只是给我一个方盒,࢚。这不是给我“∂”。
Paul Reiners

18
危险,威尔·鲁滨逊!不要忘记Unicode代码点不一定适合char。因此,您需要提前绝对确定您的值c小于0x10000,否则这种方法将严重破坏。
大卫

1
@NickHartley抱歉,不要关注---您是否将0x10000误读为10000?
大卫

10
这就是为什么我说“在下面”!我需要强调的是,尽管Java字符最多只能达到0xffff,但Unicode代码点最多可以达到0xfffff。设计Java后,Unicode标准发生了变化。这些天来,Java字符从技术上讲包含UTF-16单词,而不是Unicode代码点,并且当您的应用程序遇到外来脚本时,忘记使用Java字符会导致可怕的破坏。
大卫

3
@DavidGiven感谢您Java chars go up to 0xFFFF。我不知道。
托尼·恩尼斯

128

如果您希望将UTF-16编码的代码单元作为char,则可以解析该整数并将其转换为其他整数所建议的值。

如果要支持所有代码点,请使用Character.toChars(int)。这将处理代码点无法容纳单个char值的情况。

Doc说:

将指定的字符(Unicode代码点)转换为存储在char数组中的UTF-16表示形式。如果指定的代码点是BMP(基本多语言平面或平面0)值,则所得的char数组具有与codePoint相同的值。如果指定的代码点是辅助代码点,则所得的char数组具有相应的代理对。


尽管这是一个更通用的解决方案,并且在许多情况下,您应该在已接受的答案上使用此方法,但已接受的答案与Paul所要求的特定问题更加接近。
Jochem Kuijpers,2013年

2
首先,谢谢!在Scala中,我仍然无法解析大于的字符charscala> "👨‍🎨".map(_.toInt).flatMap((i: Int) => Character.toChars(i)).map(_.toHexString)给出了res11: scala.collection.immutable.IndexedSeq[String] = Vector(f468, 200d, f3a8) 这个表情符号,即“男歌手”,用三个代码点进行寻址U+1f468U+200dU+1f3a8。缺少最重要的数字。我可以按位或(stackoverflow.com/a/2220476/1007926)添加它,但不知道如何确定哪些已解析的字符已被截断。谢谢!
彼得·贝西奇

1
@JochemKuijpers我不同意“接受的答案与特定问题更接近”。OP明确询问如果知道符号的Unicode编号,该如何构造符号?” ,并且如果该“ Unicode编号”在BMP之外,则接受的答案将不起作用。例如,有效代码点0x1040C接受的答案失败,因为它在SMP中。这是一个较差的答案,应予以纠正或删除。
skomisa

@skomisa OPs场景仅限于十六进制Unicode转义序列的表示形式。如果您有一个应该被编码为代理对的字符,那么这将反映在这些转义序列中,因此最终还是可以解决的。正如我所说的,这是一个更通用的解决方案,您应该使用它。
Jochem Kuijpers

20

这里的其他答案要么仅支持unicode直到U + FFFF(答案仅处理一个char实例),要么不告诉如何获取实际符号(答案停止于Character.toChars()或使用错误的方法)之后),因此在这里也添加我的答案。

为了也支持补充代码点,这是需要做的:

// this character:
// http://www.isthisthingon.org/unicode/index.php?page=1F&subpage=4&glyph=1F495
// using code points here, not U+n notation
// for equivalence with U+n, below would be 0xnnnn
int codePoint = 128149;
// converting to char[] pair
char[] charPair = Character.toChars(codePoint);
// and to String, containing the character we want
String symbol = new String(charPair);

// we now have str with the desired character as the first item
// confirm that we indeed have character with code point 128149
System.out.println("First code point: " + symbol.codePointAt(0));

我还快速测试了哪些转换方法有效,哪些无效

int codePoint = 128149;
char[] charPair = Character.toChars(codePoint);

String str = new String(charPair, 0, 2);
System.out.println("First code point: " + str.codePointAt(0));    // 128149, worked
String str2 = charPair.toString();
System.out.println("Second code point: " + str2.codePointAt(0));  // 91, didn't work
String str3 = new String(charPair);
System.out.println("Third code point: " + str3.codePointAt(0));   // 128149, worked
String str4 = String.valueOf(codePoint);
System.out.println("Fourth code point: " + str4.codePointAt(0));  // 49, didn't work
String str5 = new String(new int[] {codePoint}, 0, 1);
System.out.println("Fifth code point: " + str5.codePointAt(0));   // 128149, worked

为什么单线工作不起作用?new String(Character.toChars(121849));在Eclipse控制台中中断,但三行版本有效。
Noumenon

@Noumenon无法重现该问题,对我而言同样有效
eis

感谢进一步。对于str4作业,不code应该codePoint代替吗?
skomisa

6

请记住,这char是一个整数类型,因此可以赋予一个整数值以及一个char常量。

char c = 0x2202;//aka 8706 in decimal. \u codepoints are in hex.
String s = String.valueOf(c);

那只是给我一个方盒,࢚。不是给我“∂”。
Paul Reiners

3
那是因为2202不是int您想要的。您正在寻找0x2202。我的错。无论如何,如果您拥有所需int的代码点,则可以将其转换为char,然后使用它(String如果需要,可以构造一个)。
ILMTitan 2011年


4
String st="2202";
int cp=Integer.parseInt(st,16);// it convert st into hex number.
char c[]=Character.toChars(cp);
System.out.println(c);// its display the character corresponding to '\u2202'.

1
尽管这篇文章可能会回答这个问题,但是您需要对自己的工作做一个解释。来提高答案的质量和可读性
Ajil O.

1
谢谢,这真的帮了我!效果很好,并且比此处的其他解决方案更容易(确实,Java人员太喜欢使事情变得过于复杂)。
parsecer

2

这是您的操作方式:

int cc = 0x2202;
char ccc = (char) Integer.parseInt(String.valueOf(cc), 16);
final String text = String.valueOf(ccc);

该解决方案由ArneVajhøj提供。


你是说这有用吗?如果是这样,这是可行的,因为您将2000、200和2重新解释为0x2202,这当然完全不是一回事。
dty

4
哦,不,等等!Unicode值(Java源中的\ u转义序列)为十六进制!所以这是正确的。您只是通过说来误导所有人int c = 2202,这是错误的!一个比这更好的解决方案很容易说int c = 0x2202,它将节省您通过字符串等的操作
。– dty

3
+1 @dty:绝对不要求中间char ccc...一行。只需使用int cc = 0x2202;然后final String text=String.valueOf(cc);
Andrew Coonce 2015年

2

尽管这是一个古老的问题,但是在今天发布的Java 11中,有一个非常简单的方法可以做到这一点:您可以使用Character.toString()的新重载

public static String toString​(int codePoint)

Returns a String object representing the specified character (Unicode code point). The result is a string of length 1 or 2, consisting solely of the specified codePoint.

Parameters:
codePoint - the codePoint to be converted

Returns:
the string representation of the specified codePoint

Throws:
IllegalArgumentException - if the specified codePoint is not a valid Unicode code point.

Since:
11

由于此方法支持任何Unicode代码点,因此返回的String的长度不必为1。

问题中给出的示例所需的代码很简单:

    int codePoint = '\u2202';
    String s = Character.toString(codePoint); // <<< Requires JDK 11 !!!
    System.out.println(s); // Prints ∂

这种方法具有几个优点:

  • 它适用于任何Unicode代码点,而不仅仅适用于可以使用Unicode处理的代码点char
  • 简洁明了,很容易理解代码在做什么。
  • 它以字符串而不是char[]通常返回的值形式返回值。如果希望将代码点返回为,则McDowell发布的答案是合适的char[]

关于此答案的一些其他说明确实使我立即明白如何创建codePoint变量。这里的语法应该是:int codePoint = 0x2202;然后:String s = Character.toString(codePoint); // <<< Requires JDK 11 !!! 或者在一个班轮:System.out.println(Character.toString(0x2202)); // Prints ∂ 希望这有助于他人使用JDK 11的这一特点
Loathian

1

下面的代码将用日语为单词“ be”编写4个unicode字符(用小数表示)。是的,日语动词“ be”有4个字符!字符的值以十进制表示,并且已被读取为String []的数组-例如使用split。如果您使用八进制或十六进制,则parseInt也会采用基数。

// pseudo code
// 1. init the String[] containing the 4 unicodes in decima :: intsInStrs 
// 2. allocate the proper number of character pairs :: c2s
// 3. Using Integer.parseInt (... with radix or not) get the right int value
// 4. place it in the correct location of in the array of character pairs
// 5. convert c2s[] to String
// 6. print 

String[] intsInStrs = {"12354", "12426", "12414", "12377"}; // 1.
char [] c2s = new char [intsInStrs.length * 2];  // 2.  two chars per unicode

int ii = 0;
for (String intString : intsInStrs) {
    // 3. NB ii*2 because the 16 bit value of Unicode is written in 2 chars
    Character.toChars(Integer.parseInt(intsInStrs[ii]), c2s, ii * 2 ); // 3 + 4
    ++ii; // advance to the next char
}

String symbols = new String(c2s);  // 5.
System.out.println("\nLooooonger code point: " + symbols); // 6.
// I tested it in Eclipse and Java 7 and it works.  Enjoy

1

这是一个打印出\u00c0到之间的Unicode字符的代码块\u00ff

char[] ca = {'\u00c0'};
for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 16; j++) {
        String sc = new String(ca);
        System.out.print(sc + " ");
        ca[0]++;
    }
    System.out.println();
}

0

不幸的是,如第一条评论所述(newbiedoodle)消除一个强烈反对并不会取得良好的结果。大多数(如果不是全部)IDE都会发出语法错误。原因在于,Java Escaped Unicode格式需要语法“ \ uXXXX”,其中XXXX是4个十六进制数字,这是必需的。尝试从片段中折叠此字符串失败。当然,“ \ u”与“ \\ u”不同。第一种语法表示转义为“ u”,第二种表示转义为反冲(即反冲),后跟“ u”。奇怪的是,在Apache页面上提供了实用程序,该实用程序正是这样做的。但实际上,它是Escape模拟效用。Apache有自己的实用程序(我没有对它们进行测试),可以为您完成这项工作。可能仍然不是您想要的。但是,该实用程序1有很好的解决方案。通过上述组合(MeraNaamJoker)。我的解决方案是创建这个转义的模拟字符串,然后将其转换回unicode(以避免真正的转义Unicode限制)。我用它来复制文本,所以有可能在uencode方法中最好使用'\\ u'而不是'\\\\ u'。试试吧。

  /**
   * Converts character to the mimic unicode format i.e. '\\u0020'.
   * 
   * This format is the Java source code format.
   * 
   *   CharUtils.unicodeEscaped(' ') = "\\u0020"
   *   CharUtils.unicodeEscaped('A') = "\\u0041"
   * 
   * @param ch  the character to convert
   * @return is in the mimic of escaped unicode string, 
   */
  public static String unicodeEscaped(char ch) {
    String returnStr;
    //String uniTemplate = "\u0000";
    final static String charEsc = "\\u";

    if (ch < 0x10) {
      returnStr = "000" + Integer.toHexString(ch);
    }
    else if (ch < 0x100) {
      returnStr = "00" + Integer.toHexString(ch);
    }
    else if (ch < 0x1000) {
      returnStr = "0" + Integer.toHexString(ch);
    }
    else
      returnStr = "" + Integer.toHexString(ch);

    return charEsc + returnStr;
  }

  /**
   * Converts the string from UTF8 to mimic unicode format i.e. '\\u0020'.
   * notice: i cannot use real unicode format, because this is immediately translated
   * to the character in time of compiling and editor (i.e. netbeans) checking it
   * instead reaal unicode format i.e. '\u0020' i using mimic unicode format '\\u0020'
   * as a string, but it doesn't gives the same results, of course
   * 
   * This format is the Java source code format.
   * 
   *   CharUtils.unicodeEscaped(' ') = "\\u0020"
   *   CharUtils.unicodeEscaped('A') = "\\u0041"
   * 
   * @param String - nationalString in the UTF8 string to convert
   * @return is the string in JAVA unicode mimic escaped
   */
  public String encodeStr(String nationalString) throws UnsupportedEncodingException {
    String convertedString = "";

    for (int i = 0; i < nationalString.length(); i++) {
      Character chs = nationalString.charAt(i);
      convertedString += unicodeEscaped(chs);
    }
    return convertedString;
  }

  /**
   * Converts the string from mimic unicode format i.e. '\\u0020' back to UTF8.
   * 
   * This format is the Java source code format.
   * 
   *   CharUtils.unicodeEscaped(' ') = "\\u0020"
   *   CharUtils.unicodeEscaped('A') = "\\u0041"
   * 
   * @param String - nationalString in the JAVA unicode mimic escaped
   * @return is the string in UTF8 string
   */
  public String uencodeStr(String escapedString) throws UnsupportedEncodingException {
    String convertedString = "";

    String[] arrStr = escapedString.split("\\\\u");
    String str, istr;
    for (int i = 1; i < arrStr.length; i++) {
      str = arrStr[i];
      if (!str.isEmpty()) {
        Integer iI = Integer.parseInt(str, 16);
        char[] chaCha = Character.toChars(iI);
        convertedString += String.valueOf(chaCha);
      }
    }
    return convertedString;
  }


-7

(答案是在DOT NET 4.5和Java中,必须存在类似的方法)

我来自印度的西孟加拉邦。据我了解,您的问题是...您想产生类似于Unicode HEX:的“অ”(孟加拉语中的字母)0X0985

现在,如果您知道关于您的语言的此值,那么您将如何产生该语言特定的Unicode符号呢?

在Dot Net中,它很简单:

int c = 0X0985;
string x = Char.ConvertFromUtf32(c);

现在,x是您的答案。但这是通过十六进制转换的十六进制,而句子到句子的转换是研究人员的工作:P


问题确实是针对Java的。我在这里看不到.NET答案的关系。
eis
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.