webentwicklung-frage-antwort-db.com.de

So konvertieren Sie eine Zeichenfolge mit Unicode-Codierung in eine Buchstabenfolge

Ich habe eine Zeichenfolge mit Unicode Encoding, \uXXXX, und möchte sie in einen regulären Buchstaben ( UTF-8 ) konvertieren. Zum Beispiel:

String myString = "\u0048\u0065\u006C\u006C\u006F World";

soll werden

"Hello World"

Ich weiß, dass ich beim Ausdrucken der Zeichenfolge Hello world anzeigt. Mein Problem ist, dass ich Dateinamen aus einer Datei auf einem Unix-Computer gelesen habe und dann danach suche. Die Dateinamen sind mit Unicode-Kodierung versehen. Wenn ich nach den Dateien suche, kann ich sie nicht finden, da sie nach einer Datei mit \uXXXX im Namen sucht.

55
SharonBL

Technisch machen:

String myString = "\u0048\u0065\u006C\u006C\u006F World";

wandelt es automatisch in "Hello World" um, ich gehe davon aus, dass Sie den String aus einer Datei lesen. Um es in "Hallo" umzuwandeln, müssen Sie den Text in die einzelnen Unicode-Ziffern einlesen (nehmen Sie den \uXXXX und erhalten Sie XXXX). Dann machen Sie Integer.ParseInt(XXXX, 16), um einen Hexadezimalwert zu erhalten, und dann char, um den tatsächlichen Wert zu ermitteln Charakter.

Edit: Etwas Code, um dies zu erreichen:

String str = myString.split(" ")[0];
str = str.replace("\\","");
String[] arr = str.split("u");
String text = "";
for(int i = 1; i < arr.length; i++){
    int hexVal = Integer.parseInt(arr[i], 16);
    text += (char)hexVal;
}
// Text will now have Hello
37
NominSim

Der Apache Commons LangStringEscapeUtils.unescapeJava () kann es richtig dekodieren. 

import org.Apache.commons.lang.StringEscapeUtils;

@Test
public void testUnescapeJava() {
    String sJava="\\u0048\\u0065\\u006C\\u006C\\u006F";
    System.out.println("StringEscapeUtils.unescapeJava(sJava):\n" + StringEscapeUtils.unescapeJava(sJava));
}


 output:
 StringEscapeUtils.unescapeJava(sJava):
 Hello
71
Tony

Sie können StringEscapeUtils von Apache Commons Lang , d.

String Title = StringEscapeUtils.unescapeJava("\u0048\u0065\u006C\u006C\u006F");

22
Pedro Lobito

Byte-Kodierungen und Strings

In Java für die Konvertierung des Byte-Streams (Byte []) in der Zeichenfolge (String) und zurück in die String-Klasse hat die folgenden Funktionen

Der Konstruktor String (byte [] bytes, String enc) empfängt den Eingabestrom von Bytes mit ihrer Kodierung. Wenn die Kodierung weggelassen wird, wird sie standardmäßig akzeptiert

getBytes Method (String enc) gibt einen Byte-Stream zurück, der in der angegebenen Codierung aufgezeichnet wurde. Die Kodierung kann auch weggelassen werden. 

try {
    String myString = "\u0048\u0065\u006C\u006C\u006F World";
    byte[] utf8Bytes = myString.getBytes("UTF8");
    String text = new String(utf8Bytes,"UTF8");
}
catch (UnsupportedEncodingException e) {
    e.printStackTrace();
}

UPDATE:

Seit Java 1.7 verwenden Sie StandardCharsets.UTF_8:

String utf8Text = "\u0048\u0065\u006C\u006C\u006F World";
byte[] bytes = utf8Text.getBytes(StandardCharsets.UTF_8);
String text = new String(bytes, StandardCharsets.UTF_8);
15
bigspawn

Diese einfache Methode wird in den meisten Fällen funktionieren, würde aber über etwas wie "u005Cu005C" stolpern, das zur Zeichenfolge "\ u0048" dekodiert werden sollte, tatsächlich aber "H" dekodieren würde, da beim ersten Durchlauf "\ u0048" als Arbeitszeichenfolge erzeugt wird wird dann erneut von der while-Schleife verarbeitet.

static final String decode(final String in)
{
    String working = in;
    int index;
    index = working.indexOf("\\u");
    while(index > -1)
    {
        int length = working.length();
        if(index > (length-6))break;
        int numStart = index + 2;
        int numFinish = numStart + 4;
        String substring = working.substring(numStart, numFinish);
        int number = Integer.parseInt(substring,16);
        String stringStart = working.substring(0, index);
        String stringEnd   = working.substring(numFinish);
        working = stringStart + ((char)number) + stringEnd;
        index = working.indexOf("\\u");
    }
    return working;
}
7
andrew pate

Aus Ihrer Frage ist nicht ganz klar, aber ich gehe davon aus, dass Sie eine Datei haben, in der jede Zeile dieser Datei einen Dateinamen hat. Und jeder Dateiname ist ungefähr so:

\u0048\u0065\u006C\u006C\u006F

Mit anderen Worten, die Zeichen in der Datei mit den Dateinamen sind \, u, 0, 0, 4, 8 und so weiter.

Wenn ja, wird erwartet, was Sie sehen. Java übersetzt \uXXXX-Sequenzen nur in String-Literalen im Quellcode (und beim Einlesen gespeicherter Properties-Objekte). Wenn Sie den Inhalt Ihrer Datei lesen, erhalten Sie eine Zeichenfolge bestehend aus den Zeichen \, u, 0, 0, 4, 8 und so weiter und nicht die Zeichenfolge Hello.

Daher müssen Sie diese Zeichenfolge analysieren, um die Teile 0048, 0065 usw. extrahieren, in chars konvertieren und aus diesen chars eine Zeichenfolge erstellen und diese Zeichenfolge an die Routine übergeben, die die Datei öffnet.

4
QuantumMechanic

Kürzere Version:

public static String unescapeJava(String escaped) {
    if(escaped.indexOf("\\u")==-1)
        return escaped;

    String processed="";

    int position=escaped.indexOf("\\u");
    while(position!=-1) {
        if(position!=0)
            processed+=escaped.substring(0,position);
        String token=escaped.substring(position+2,position+6);
        escaped=escaped.substring(position+6);
        processed+=(char)Integer.parseInt(token,16);
        position=escaped.indexOf("\\u");
    }
    processed+=escaped;

    return processed;
}
3
ssuukk

versuchen

private static final Charset UTF_8 = Charset.forName("UTF-8");
private String forceUtf8Coding(String input) {return new String(input.getBytes(UTF_8), UTF_8))}
3
haohcraft

eine einfache Möglichkeit, die ich mit JsonObject kenne:

try {
    JSONObject json = new JSONObject();
    json.put("string", myString);
    String converted = json.getString("string");

} catch (JSONException e) {
    e.printStackTrace();
}
1
Ashkan Ghodrat

Ich habe eine performante und fehlersichere Lösung geschrieben:

public static final String decode(final String in) {
    int p1 = in.indexOf("\\u");
    if (p1 < 0)
        return in;
    StringBuilder sb = new StringBuilder();
    while (true) {
        int p2 = p1 + 6;
        if (p2 > in.length()) {
            sb.append(in.subSequence(p1, in.length()));
            break;
        }
        try {
            int c = Integer.parseInt(in.substring(p1 + 2, p1 + 6), 16);
            sb.append((char) c);
            p1 += 6;
        } catch (Exception e) {
            sb.append(in.subSequence(p1, p1 + 2));
            p1 += 2;
        }
        int p0 = in.indexOf("\\u", p1);
        if (p0 < 0) {
            sb.append(in.subSequence(p1, in.length()));
            break;
        } else {
            sb.append(in.subSequence(p1, p0));
            p1 = p0;
        }
    }
    return sb.toString();
}
0
neoedmund

StringEscapeUtils aus der org.Apache.commons.lang3-Bibliothek ist veraltet ab 3.6.

Sie können stattdessen die neue commons-text Bibliothek verwenden:

compile 'org.Apache.commons:commons-text:1.7'

OR

<dependency>
   <groupId>org.Apache.commons</groupId>
   <artifactId>commons-text</artifactId>
   <version>1.7</version>
</dependency>

Beispielcode:

org.Apache.commons.text.StringEscapeUtils.unescapeJava(escapedString);
0

Hier ist meine Lösung ...

                String decodedName = JwtJson.substring(startOfName, endOfName);

                StringBuilder builtName = new StringBuilder();

                int i = 0;

                while ( i < decodedName.length() )
                {
                    if ( decodedName.substring(i).startsWith("\\u"))
                    {
                        i=i+2;
                        builtName.append(Character.toChars(Integer.parseInt(decodedName.substring(i,i+4), 16)));
                        i=i+4;
                    }
                    else
                    {
                        builtName.append(decodedName.charAt(i));
                        i = i+1;
                    }
                };
0
AndyW58

Aktualisierungen bezüglich Antworten, die die Verwendung von The Apache Commons Lang vorschlagen, StringEscapeUtils.unescapeJava () Es wurde nicht mehr unterstützt. Der Ersatz ist Apache Commons Text s StringEscapeUtils.unescapeJava ()

0
user7294900

Zwei weitere Möglichkeiten, das zu tun, wären

//This is what StringBuilder internally does on calling toString() Method
char[] charArray = "\u0048\u0065\u006C\u006C\u006F World".toCharArray();
String output = new String(charArray, 0, charArray.length);
//To do it in single line 
String output = new StringBuilder("\u0048\u0065\u006C\u006C\u006F World").toString();
0
Manoj Krishna

Ich fand heraus, dass viele der Antworten das Thema "Ergänzungszeichen" nicht angesprochen haben. Hier ist der richtige Weg, um es zu unterstützen. Keine Fremdanbieter-Bibliotheken, reine Java-Implementierung.

http://www.Oracle.com/us/technologies/Java/supplementary-142654.html

public static String fromUnicode(String unicode) {
    String str = unicode.replace("\\", "");
    String[] arr = str.split("u");
    StringBuffer text = new StringBuffer();
    for (int i = 1; i < arr.length; i++) {
        int hexVal = Integer.parseInt(arr[i], 16);
        text.append(Character.toChars(hexVal));
    }
    return text.toString();
}

public static String toUnicode(String text) {
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < text.length(); i++) {
        int codePoint = text.codePointAt(i);
        // Skip over the second char in a surrogate pair
        if (codePoint > 0xffff) {
            i++;
        }
        String hex = Integer.toHexString(codePoint);
        sb.append("\\u");
        for (int j = 0; j < 4 - hex.length(); j++) {
            sb.append("0");
        }
        sb.append(hex);
    }
    return sb.toString();
}

@Test
public void toUnicode() {
    System.out.println(toUnicode("????"));
    System.out.println(toUnicode("????"));
    System.out.println(toUnicode("Hello World"));
}
// output:
// \u1f60a
// \u1f970
// \u0048\u0065\u006c\u006c\u006f\u0020\u0057\u006f\u0072\u006c\u0064

@Test
public void fromUnicode() {
    System.out.println(fromUnicode("\\u1f60a"));
    System.out.println(fromUnicode("\\u1f970"));
    System.out.println(fromUnicode("\\u0048\\u0065\\u006c\\u006c\\u006f\\u0020\\u0057\\u006f\\u0072\\u006c\\u0064"));
}
// output:
// ????
// ????
// Hello World
0
lovestackh343

Eine alternative Möglichkeit, dies zu erreichen, könnte darin bestehen, chars() zu verwenden, das mit Java 9 eingeführt wurde. Dies kann verwendet werden, um die Zeichen zu durchlaufen und jedes Zeichen zu überprüfen, das einem Ersatzcode) zugeordnet wird Punkt wird nicht interpretiert durchlaufen. Dies kann verwendet werden als: -

String myString = "\u0048\u0065\u006C\u006C\u006F World";
myString.chars().forEach(a -> System.out.print((char)a));
// would print "Hello World"
0
nullpointer

Lösung für Kotlin:

val result = String(someText.toByteArray())

Kotlin verwendet UTF-8 überall als Standardcodierung

Sie können es auch als Erweiterung für die String-Klasse implementieren:

fun String.unescape(): String {
    return String(this.toByteArray())
}

und dann einfach verwenden:

val result = someText.unescape()

;)

0
Evgeny Lebedev

Eigentlich habe ich eine Open Source-Bibliothek geschrieben, die einige Dienstprogramme enthält. Eine davon konvertiert eine Unicode-Sequenz in String und umgekehrt. Ich fand es sehr nützlich. Hier ist das Zitat aus dem Artikel über diese Bibliothek zum Unicode-Konverter:

Die Klasse StringUnicodeEncoderDecoder verfügt über Methoden, die eine .__ konvertieren können. Zeichenfolge (in einer beliebigen Sprache) in eine Folge von Unicode-Zeichen und vise-umgekehrt. Zum Beispiel wird ein String "Hello World" in konvertiert

"u0048\u0065\u006c\u006c\u006f\u0020\u0057\u006f\u0072\u006c\u0064"

und kann wieder hergestellt werden.

Hier ist der Link zum gesamten Artikel, in dem erläutert wird, welche Dienstprogramme in der Bibliothek vorhanden sind und wie die Bibliothek dazu verwendet werden kann. Es ist als Maven-Artefakt oder als Quelle von Github erhältlich. Es ist sehr einfach zu bedienen. Open-Source-Java-Bibliothek mit Stack-Trace-Filterung, Analyse des Unicode-Konverters für Silent String und Versionsvergleich

0
Michael Gantman