Ruft den Unicode-Wert eines Zeichens ab

68

Gibt es in Java eine Möglichkeit, ein Unicode-Äquivalent für ein beliebiges Zeichen zu erhalten? z.B

Angenommen, eine Methode getUnicode(char c). Ein Anruf getUnicode('÷')sollte zurückkehren \u00f7.

Saurabh
quelle
Zeichen sind in Java bereits Unicode.
Mostowski Zusammenbruch

Antworten:

65

Sie können dies für jedes Java-Zeichen mit dem einen Liner hier tun:

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

Aber es wird nur für die Unicode-Zeichen bis zu Unicode 3.0 funktionieren, weshalb ich davon ausgegangen bin, dass Sie dies für jedes Java-Zeichen tun können.

Da Java schon lange vor Unicode 3.1 entwickelt wurde und daher das Zeichenprimitiv von Java nicht ausreicht, um Unicode 3.1 und höher darzustellen, gibt es keine Zuordnung mehr "ein Unicode-Zeichen zu einem Java-Zeichen" (stattdessen wird ein monströser Hack verwendet).

Sie müssen hier also wirklich Ihre Anforderungen überprüfen: Müssen Sie Java-Zeichen oder ein mögliches Unicode-Zeichen unterstützen?

SyntaxT3rr0r
quelle
Vielen Dank. Ich habe alle Zeichen auf diese Weise überprüft und es sieht vorerst gut aus.
Saurabh
4
Der "monströse Hack" ist UTF-16, der weit verbreitet ist. Es ist vielleicht nicht ideal, aber es ist gut verstanden und viel besser als nur UCS-2 zu unterstützen.
Joachim Sauer
1
@ Joachim: Es ist jedoch hässlich, String.charAtjetzt "ein halbes Zeichen" zurückzugeben und String.lengthetwas zurückzugeben, das sich von der Anzahl der Zeichen unterscheiden kann, nicht wahr ? (Zeichen bedeutet hier Unicode-Codepunkt, nicht Java-Zeichen) Die String-Klasse sollte (und war vor Unicode 3.1) unabhängig von Codierungsproblemen sein.
Thilo
1
@ Joachim: Ich habe mich genau auf das bezogen, was Thilo beschrieben hat. Für mich ist das eigentliche Problem, dass wir zur Wahrung der Abwärtskompatibilität eine Methode haben, charAt (...), die KEIN Zeichen zurückgibt. Und das ist schlecht. Der Methodenname ist gleich geblieben, aber Javadoc wurde neu geschrieben. Und jetzt haben wir codePointAt (...), von dem kaum jemand etwas weiß, und trotzdem ist das Problem sehr verwirrend. Nicht Javas Designer sind per se schuld, denn wie ich in meiner Antwort schrieb, wurde Java lange vor der Veröffentlichung von Unicode 3.1 entwickelt. Es ist nur ein bisschen traurig, dass char 16 Bit statt 32 ist.
SyntaxT3rr0r
Ja, das ist mir bewusst und es ist ein Problem. Das leugne ich nicht. Aber zumindest haben wir eine gut verstandene "Lösung" (oder besser gesagt eine Problemumgehung), anstatt in dieselbe Codierungshölle zu geraten, die das ganze Problem "Oh nein! Viele Leute können ihre Sprache nicht mit ASCII schreiben" erzeugt hat. UTF-16 ist nicht ideal, aber es ist standardisiert und gut verstanden.
Joachim Sauer
34

Wenn Sie Java 5 haben, verwenden Sie char c = ...; String s = String.format ("\\u%04x", (int)c);

Wenn Ihre Quelle kein Unicode-Zeichen ( char), sondern ein String ist, müssen charAt(index)Sie das Unicode-Zeichen an Position bringen index.

Nicht verwenden, codePointAt(index)da dies 24-Bit-Werte (vollständiger Unicode) zurückgibt, die nicht mit nur 4 Hex-Ziffern dargestellt werden können (es werden 6 benötigt). Eine Erklärung finden Sie in den Dokumenten .

[EDIT] Um es klar zu machen: Diese Antwort verwendet nicht Unicode, sondern die Methode, mit der Java Unicode-Zeichen (dh Ersatzpaare) darstellt, da char 16 Bit und Unicode 24 Bit ist. Die Frage sollte lauten: "Wie kann ich charin eine 4-stellige Hex-Zahl konvertieren ?", Da es nicht (wirklich) um Unicode geht.

Aaron Digulla
quelle
2
@ Aaron Digulla: Es ist ein häufiger Fehler zu glauben, dass charAt (...) ein Unicode-Zeichen zurückgibt. Das tut es nicht. charAt (...) gibt nur dann ein Unicode-Zeichen zurück, wenn Ihr String aus Unicode 3.0 / BMP-Zeichen besteht. Ich bin nicht der Meinung, dass er codePointAt nicht verwenden sollte. Er sollte codePointAt und eine Methode verwenden, mit der Zeichen außerhalb des BMP codiert werden können.
SyntaxT3rr0r
codePointAt wäre besser, aber wenn Sie es wirklich brauchen, wird es schwierig, den richtigen Wert für den Index herauszufinden.
Thilo
Aus der Frage (4-stelliges Hex) geht hervor, dass Saurabh nicht wirklich an echten Unicode-Zeichen interessiert ist (weil sie nicht in 4 hexadezimale Ziffern passen), daher wäre die Verwendung von codePointAt () falsch.
Aaron Digulla
@WizardOfOdds: Haben Sie ein funktionierendes Beispiel, wie Sie die Indizes erhalten, die Sie zum Aufrufen von codePointAt benötigen?
Aaron Digulla
@ Aaron Digulla: Die Sache ist, es gibt keine Indexmagie beim Aufrufen von codePointAt (...). codePointAt (...) gibt immer ein Unicode-Zeichen zurück, auch wenn es sich außerhalb des BMP befindet. Wenn Sie charAt (...) aufrufen, können Probleme auftreten, denn wenn Sie charAt (...) nach einem Unicode-Zeichen außerhalb des BMP aufrufen, gibt es keine Garantie dafür, dass Sie ein Zeichen lesen. Aber vielleicht habe ich dich falsch verstanden? Es gibt Beispiele mit String, der Musiknoten enthält (das sind Zeichen außerhalb des BMP), wenn ich mich richtig erinnere. Aber vielleicht habe ich Ihre Frage falsch verstanden?
SyntaxT3rr0r
13
private static String toUnicode(char ch) {
    return String.format("\\u%04x", (int) ch);
}
Yogesh Dubey
quelle
7
Kopiert eine vorhandene Antwort aus 3 Jahren zuvor.
James.garriss
3
( "\\u" + Integer.toHexString('÷' | 0x10000).substring(1) )
Dennoch
"\\ u" + String.format ("% 04x", (int) c) .toUpperCase ()
fl0w
6
char c = 'a';
String a = Integer.toHexString(c); // gives you---> a = "61"
Deepak Sharma
quelle
1

Ich habe diesen schönen Code im Web gefunden.

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();
  }
 }
}

Originaler Artikel

Chathuranga Chandrasekara
quelle
Vielen Dank. Du gibst mir was ich gefragt habe. Wenn ich jedoch einige russische Zeichen versuche, wird der gleiche Unicode-Wert zurückgegeben. Ich denke, der Unicode-Wert sollte für verschiedene Zeichen unterschiedlich sein. Ich habe versucht, folgende Zeichen zu verwenden - л, и, ц, т, я retuns \ u003F.
Saurabh
1
Ich bin mir ziemlich sicher, dass dieser Code für Codepunkte über 0xFFFF nicht korrekt ist.
SyntaxT3rr0r
1
Russische Zeichen sollten sich jedoch in der mehrsprachigen Grundebene befinden (unter 0xFFFF).
Thilo
@Thilo: Oh, ich weiß, ich habe Saurabhs russisches Beispiel nicht kommentiert. Ich habe seine Charaktere mit meiner Methode ausprobiert, bevor ich den Kommentar gepostet habe, und sie funktionieren einwandfrei. Ich habe nur gesagt, dass ich ziemlich sicher bin, dass die Methode dort nicht mit Zeichen außerhalb des BMP funktioniert.
SyntaxT3rr0r
2
Es ist erstaunlich, wie viel Code jemand schreiben muss, um ein einfaches Problem zu lösen. Aarons Lösung war 40 Zeichen lang. Hier haben wir 1124.
jarnbjo
0

Sind Sie mit der Verwendung von Unicode wählerisch, weil es mit Java einfacher ist, wenn Sie Ihr Programm so schreiben, dass es den Wert "dec" oder (HTML-Code) verwendet, können Sie einfach Datentypen zwischen char und int umwandeln

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

Gibt diese Ausgabe

b
98
100
d
Jordan Doerksen
quelle
0

Zuerst bekomme ich die hohe Seite des Saiblings. Holen Sie sich danach die niedrige Seite. Konvertieren Sie alle Dinge in HexString und geben Sie das Präfix ein.

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);
Josiel Novaes
quelle