2009-12-20 8 views
5

Ich baue eine Sprache, eine Spielzeugsprache. Die Syntax \#0061 sollte die gegebene Unicode zu einem Zeichen konvertieren:Konvertierung von Unicode zu String in Java

String temp = yytext().subtring(2); 

Dann danach versucht '\u' auf den String anhängen, bemerkte ich, dass ein Fehler erzeugt.

Ich habe auch versucht, "\\" + "u" + temp; dieser Weg macht keine Umwandlung.

Ich versuche im Grunde, Unicode in ein Zeichen zu konvertieren, indem ich nur '0061' zu einer Methode, Hilfe.

+0

Beachten Sie, dass 16 Bit (4 Hexadezimalziffern) nicht ausreichen, um alle Zeichen in Unicode darzustellen. In Java ordnet "\ u1234" einer Codepunkteinheit in UTF-16 zu, die nicht mit einem Zeichen identisch ist. –

+0

Nachtrag: Tatsächlich ist es der Java-Datentyp char, der auf UTF-16-Code-Point-Units, nicht auf tatsächliche Unicode-Zeichen, abgebildet wird. –

Antwort

11

Entfernen Sie das '#' und verwenden Sie Integer.parseInt("0061", 16), um die Hexadezimalziffern in int zu konvertieren. Dann werfen Sie eine char.

(Wenn Sie den Lexer von Hand implementiert hätten, wäre eine Alternative, die Konvertierung im laufenden Betrieb durchzuführen, da Ihr Lexer mit dem Unicode-Literal übereinstimmt. Aber beim erneuten Lesen der Frage sehe ich, dass Sie einen Lexer-Generator verwenden. . guter Zug!)

+1

Nur neugierig: Wie haben Sie festgestellt, dass er einen Lexer verwendet? – BalusC

+1

@BalusC Wegen 'yytext', eine lexspezifische Variable –

+0

Das stimmt Pascal –

0

\uXXXX ist eine Escape-Sequenz. Vor der Ausführung wurde es bereits in den tatsächlichen Zeichenwert konvertiert, der zur Laufzeit nicht zur Laufzeit "ausgewertet" wird.

Wahrscheinlich möchten Sie eine Zuordnung von Ihrer #XXXX-Syntax zu Unicode-Codepunkten definieren und sie in char umwandeln.

2

Sie müssen den bestimmten Codepunkt in einen char konvertieren. Sie können mit ein wenig Hilfe von regex tun:

String string = "blah #0061 blah"; 

Matcher matcher = Pattern.compile("\\#((?i)[0-9a-f]{4})").matcher(string); 
while (matcher.find()) { 
    int codepoint = Integer.valueOf(matcher.group(1), 16); 
    string = string.replaceAll(matcher.group(0), String.valueOf((char) codepoint)); 
} 

System.out.println(string); // blah a blah 

bearbeiten nach den Kommentaren, wenn es sich um ein einzelnes Token ist, dann tun nur:

String string = "0061"; 
char c = (char) Integer.parseInt(string, 16); 
System.out.println(c); // a 
+0

Ähm ... du willst keinen lexikalischen Analysator mit Java Regex Pattern Matching implementieren. –

+0

Gültiger Punkt, ich habe die Antwort entsprechend aktualisiert. – BalusC

+0

Ich brauche etwas wie das erste Beispiel, das Sie gepostet haben. Ich habe den Code ausgeführt, der das Muster ändert, so wie ich sie brauche, aber ReplaceAll ersetzt nichts. Die Zeichenkette ist die gleiche wie die ursprüngliche Zeichenkette :( –

2

ich im Grunde bin versucht, Unicode in ein Zeichen zu konvertieren, indem nur '0061' zu einer Methode, Hilfe.

char fromUnicode(String codePoint) { 
    return (char) Integer.parseInt(codePoint, 16); 
} 

Sie müssen schlechte Eingaben und so zu handhaben, aber das wird anders funktionieren.