Creando un carácter Unicode a partir de su número

114

Quiero mostrar un carácter Unicode en Java. Si hago esto, funciona bien:

String symbol = "\u2202";

símbolo es igual a "∂". Eso es lo que quiero.

El problema es que conozco el número Unicode y necesito crear el símbolo Unicode a partir de eso. Probé (para mí) lo obvio:

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

Sin embargo, en este caso, el símbolo es igual a "\ u2202". Eso no es lo que quiero.

¿Cómo puedo construir el símbolo si conozco su número Unicode (pero solo en tiempo de ejecución --- no puedo codificarlo como en el primer ejemplo)?

Paul Reiners
fuente
1
Elimine la primera barra invertida, de modo que en lugar de escapar de la barra invertida, escape de la secuencia Unicode. El uso de "\\" le dice a Java que desea imprimir "\", no usarlo como pasado de una secuencia de escape para caracteres Unicode. Si elimina el primero, se escapará de la secuencia Unicode y no de la segunda barra invertida. Al menos, según mi leal saber y entender.
Financia la demanda de Monica

Respuestas:

73

Solo envía tu inta char. Puedes convertir eso en un Stringuso Character.toString():

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

EDITAR:

Solo recuerde que las secuencias de escape en el código fuente de Java (los \ubits) están en HEX, por lo que si está tratando de reproducir una secuencia de escape, necesitará algo como int c = 0x2202.

dty
fuente
3
Eso solo me da una caja cuadrada, ࢚. No me está dando "∂".
Paul Reiners
19
¡Peligro, Will Robinson! No olvide que los puntos de código Unicode no encajarán necesariamente en un char . Por lo tanto, debe estar absolutamente seguro de antemano de que su valor de ces menor que 0x10000, o de lo contrario, este enfoque se romperá horriblemente.
David dado
1
@NickHartley Lo siento, no sigas --- ¿Leíste mal 0x10000 por 10000?
David Given
10
¡Por eso dije 'abajo'! Y debo enfatizar que, a pesar del hecho de que los caracteres de Java solo suben hasta 0xffff, los puntos de código Unicode suben hasta 0xfffff. El estándar Unicode se cambió después de que se diseñó Java. En estos días, los caracteres Java contienen técnicamente palabras UTF-16, no puntos de código Unicode, y olvidar esto provocará una rotura horrible cuando su aplicación encuentre un script exótico.
David dado
3
@DavidGiven gracias por Java chars go up to 0xFFFF. No sabía eso.
Tony Ennis
128

Si desea obtener una unidad de código codificado en UTF-16 como unidad char, puede analizar el entero y convertirlo como han sugerido otros.

Si desea admitir todos los puntos de código, use Character.toChars(int). Esto manejará los casos en los que los puntos de código no caben en un solo charvalor.

Doc dice:

Convierte el carácter especificado (punto de código Unicode) en su representación UTF-16 almacenada en una matriz de caracteres. Si el punto de código especificado es un valor BMP (Basic Multilingual Plane o Plane 0), la matriz de caracteres resultante tiene el mismo valor que codePoint. Si el punto de código especificado es un punto de código suplementario, la matriz de caracteres resultante tiene el par suplente correspondiente.

McDowell
fuente
Si bien esta es una solución más general y, en muchos casos, debe usarla en lugar de la respuesta aceptada, la respuesta aceptada coincide más con el problema específico que pidió Paul.
Jochem Kuijpers
2
¡En primer lugar, gracias! En Scala, todavía no puedo analizar caracteres que son más grandes que un char. scala> "👨‍🎨".map(_.toInt).flatMap((i: Int) => Character.toChars(i)).map(_.toHexString)da res11: scala.collection.immutable.IndexedSeq[String] = Vector(f468, 200d, f3a8) Este emoji, "cantante masculino", se aborda con los tres puntos de código U+1f468, U+200dy U+1f3a8. Falta el dígito más significativo. Puedo agregarlo con un OR bit a bit ( stackoverflow.com/a/2220476/1007926 ), pero no sé cómo determinar qué caracteres analizados se han truncado. ¡Gracias!
Peter Becich
1
@JochemKuijpers No estoy de acuerdo con que "la respuesta aceptada sea más cercana al problema específico" . El OP preguntó explícitamente "¿Cómo puedo construir el símbolo si conozco su número Unicode ...?" , y la respuesta aceptada no puede funcionar si ese "número Unicode" está fuera del BMP. Por ejemplo, la respuesta aceptada falla para el punto de código válido 0x1040C porque está en el SMP. Es una respuesta deficiente y debe corregirse o eliminarse.
skomisa
El escenario de @skomisa OPs se limita a la representación de la secuencia de escape Unicode hexadecimal. Si tiene un carácter que debe codificarse como un par sustituto, eso se refleja en estas secuencias de escape, por lo que al final aún funciona. Como dije, esta es una solución más general y debería usarla.
Jochem Kuijpers
20

Las otras respuestas aquí solo admiten unicode hasta U + FFFF (las respuestas se refieren a una sola instancia de char) o no dicen cómo llegar al símbolo real (las respuestas se detienen en Character.toChars () o usan un método incorrecto después de eso), por lo que también agrego mi respuesta aquí.

Para admitir también puntos de código suplementarios, esto es lo que se debe hacer:

// 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));

También hice una prueba rápida sobre qué métodos de conversión funcionan y cuáles no

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
eis
fuente
¿Por qué no funciona como una sola línea? new String(Character.toChars(121849));se rompe en la consola de Eclipse, pero la versión de tres líneas funciona.
Noumenon
@Noumenon no puede reproducir el problema, funciona igual de bien para mí
EIS
Felicitaciones por ir más lejos. Para la str4tarea, ¿no debería codeser codePointen su lugar?
skomisa
6

Recuerde que chares un tipo integral y, por lo tanto, se le puede dar un valor entero, así como una constante char.

char c = 0x2202;//aka 8706 in decimal. \u codepoints are in hex.
String s = String.valueOf(c);
ILMTitan
fuente
Eso solo me da una caja cuadrada, ࢚. No me está dando "∂".
Paul Reiners
3
Eso es porque 2202 no es lo intque estabas buscando. Estaba buscando 0x2202. Mi culpa. En cualquier caso, si tiene el intpunto de código que está buscando, puede simplemente convertirlo en a char, y usarlo (para construir a Stringsi lo desea).
ILMTitan
6

Este funcionó bien para mí.

  String cc2 = "2202";
  String text2 = String.valueOf(Character.toChars(Integer.parseInt(cc2, 16)));

Ahora text2 tendrá ∂.

MeraNaamJoker
fuente
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'.
Kapil K. Kushwah
fuente
1
Si bien esta publicación puede responder a la pregunta, se requiere una explicación de lo que está haciendo; para mejorar la calidad y la legibilidad de su respuesta
Ajil O.
1
Gracias, ¡realmente me ayudó! Funciona bien y es más fácil que otras soluciones aquí (realmente, a la gente de Java le gusta complicar demasiado las cosas).
parsecer
2

Así es como lo haces:

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

Esta solución es de Arne Vajhøj.

Paul Reiners
fuente
¿Estás diciendo que esto funciona? Si es así, esto funciona porque estás reinterpretando dos mil doscientos dos como 0x2202, que, por supuesto, no es lo mismo en absoluto.
dty
4
¡Oh, no, espera! Los valores Unicode (las secuencias de escape \ u en la fuente Java) SON hexadecimales. Entonces esto es correcto. Simplemente engañó a todos al decir int c = 2202, ¡lo cual está mal! Una solución mejor que esta es simple de decir int c = 0x2202que le ahorrará pasar por una cadena, etc.
dty
3
+1 @dty: No hay absolutamente ninguna llamada para la char ccc...línea media . Solo use int cc = 0x2202;y luegofinal String text=String.valueOf(cc);
Andrew Coonce
2

Aunque esta es una pregunta antigua, hay una forma muy fácil de hacer esto en Java 11 que se lanzó hoy: puede usar una nueva sobrecarga de 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

Dado que este método admite cualquier punto de código Unicode, la longitud de la cadena devuelta no es necesariamente 1.

El código necesario para el ejemplo dado en la pregunta es simplemente:

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

Este enfoque ofrece varias ventajas:

  • Funciona para cualquier punto de código Unicode en lugar de solo para aquellos que se pueden manejar con un char.
  • Es conciso y fácil de entender lo que hace el código.
  • Devuelve el valor como una cadena en lugar de como char[], que suele ser lo que desea. La respuesta publicada por McDowell es apropiada si desea que el punto de código se devuelva como char[].
skomisa
fuente
Algunas aclaraciones adicionales sobre esto, ya que esta respuesta me hizo evidente de inmediato cómo crear la variable codePoint. La sintaxis aquí debería ser: int codePoint = 0x2202;Entonces: String s = Character.toString(codePoint); // <<< Requires JDK 11 !!! O en una sola línea: System.out.println(Character.toString(0x2202)); // Prints ∂ Espero que esto ayude a alguien más a usar esta función de JDK 11.
Loathian
1

El siguiente código escribirá los 4 caracteres Unicode (representados por decimales) para la palabra "be" en japonés. Sí, el verbo "ser" en japonés tiene 4 caracteres. El valor de los caracteres está en decimal y se ha leído en una matriz de String [], utilizando split, por ejemplo. Si tienes Octal o Hex, parseInt también toma una base.

// 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
user96265
fuente
1

Aquí hay un bloque para imprimir caracteres Unicode entre \u00c0para \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();
}
fjiang_ca
fuente
0

Desafortunadamente, eliminar una reacción violenta como se menciona en el primer comentario (newbiedoodle) no conduce a un buen resultado. La mayoría (si no todos) de IDE emite errores de sintaxis. La razón es que el formato Unicode de escape de Java espera la sintaxis "\ uXXXX", donde XXXX son 4 dígitos hexadecimales, que son obligatorios. Los intentos de doblar esta cuerda a partir de piezas fallan. Por supuesto, "\ u" no es lo mismo que "\\ u". La primera sintaxis significa 'u' de escape, la segunda significa una reacción de escape (que es una reacción) seguida de una 'u'. Es extraño, que en las páginas de Apache se presente la utilidad, que hace exactamente este comportamiento. Pero en realidad, es una utilidad de imitación de Escape. . Apache tiene algunas utilidades propias (no las probé), que hacen este trabajo por usted. Puede ser, todavía no es eso, lo que quieres tener. 1Pero esta utilidad tiene un buen enfoque para la solución. Con la combinación descrita anteriormente (MeraNaamJoker). Mi solución es crear esta cadena de mímica de escape y luego convertirla de nuevo a Unicode (para evitar la restricción real de Unicode de escape). Lo usé para copiar texto, por lo que es posible que en el método uencode sea mejor usar '\\ u' excepto '\\\\ u'. Intentalo.

  /**
   * 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;
  }
hariprasad
fuente
-1

char c = (char) 0x2202; Cadena s = "" + c;

dave110022
fuente
-7

(LA RESPUESTA ESTÁ EN DOT NET 4.5 y en java, debe existir un enfoque similar)

Soy de Bengala Occidental en INDIA. Según tengo entendido, su problema es ... Quiere producir similar a 'অ' (es una letra en idioma bengalí) que tiene Unicode HEX:0X0985 .

Ahora bien, si conoce este valor con respecto a su idioma, ¿cómo producirá ese símbolo Unicode específico del idioma, verdad?

En Dot Net es tan simple como esto:

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

Ahora x es tu respuesta. Pero esto es HEX por HEX convertir y la conversión de oración a oración es un trabajo para los investigadores: P

Suman Kr. Nath
fuente
La pregunta es de hecho para java. No veo cómo se relaciona la respuesta de .NET aquí.
EIS