90

エスケープされた Unicode 文字を含む文字列があり、それ\uXXXX通常の Unicode 文字に変換したいと考えています。例えば:

"\u0048\u0065\u006C\u006C\u006F World"

なるべき

"Hello World"

最初の文字列を印刷すると、すでに表示されていることがわかりますHello world。私の問題は、ファイルからファイル名を読み取り、それらを検索することです。ファイル内のファイル名は Unicode エンコーディングでエスケープされており、ファイルを検索すると、\uXXXX名前に を含むファイルが検索されるため、ファイルが見つかりません。

4

22 に答える 22

102

Apache Commons Lang StringEscapeUtils.unescapeJava()は正しくデコードできます。

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
于 2013-01-16T21:29:21.613 に答える
50

技術的に行う:

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

に自動的に変換されるため"Hello World"、何らかのファイルから文字列を読み込んでいると仮定します。それを「Hello」に変換するには、テキストを個別の Unicode 数字に解析する必要があります ( を取得して getを実行する\uXXXXだけですXXXX) 。Integer.ParseInt(XXXX, 16)char

編集:これを達成するためのいくつかのコード:

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
于 2012-06-21T20:01:19.513 に答える
32

Apache Commons LangStringEscapeUtilsから使用できます。つまり、次のようになります。

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

于 2013-06-20T14:27:52.383 に答える
6

org.apache.commons.lang3 ライブラリの StringEscapeUtils は、3.6で非推奨になりました。

そのため、代わりに新しいcommons-textライブラリを使用できます。

compile 'org.apache.commons:commons-text:1.9'

OR

<dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-text</artifactId>
   <version>1.9</version>
</dependency>

コード例:

org.apache.commons.text.StringEscapeUtils.unescapeJava(escapedString);
于 2019-08-17T01:55:00.510 に答える
4

あなたの質問からは完全には明らかではありませんが、そのファイルの各行がファイル名であるファイルがあると言っていると思います。そして、各ファイル名は次のようなものです:

\u0048\u0065\u006C\u006C\u006F

つまり、ファイル名のファイル内の文字は、、、、、\などです。u0048

もしそうなら、あなたが見ているものは期待されています。Java は\uXXXX、ソース コード内の文字列リテラルのシーケンスのみを変換します (および格納されたPropertiesオブジェクトを読み取る場合)。ファイルの内容を読み取ると、文字列ではなく、文字、、、、、などで構成される文字列が表示\されます。u0048Hello

したがって、その文字列を解析して、 などの部分を抽出し0048、それらをs に変換してから文字列を作成し、その文字列をファイルを開くルーチンに渡す必要があります。0065charchar

于 2012-06-21T19:57:13.457 に答える
3

正規表現を使用して、私のバージョンに貢献したかっただけです:

private static final String UNICODE_REGEX = "\\\\u([0-9a-f]{4})";
private static final Pattern UNICODE_PATTERN = Pattern.compile(UNICODE_REGEX);
...
String message = "\u0048\u0065\u006C\u006C\u006F World";
Matcher matcher = UNICODE_PATTERN.matcher(message);
StringBuffer decodedMessage = new StringBuffer();
while (matcher.find()) {
  matcher.appendReplacement(
      decodedMessage, String.valueOf((char) Integer.parseInt(matcher.group(1), 16)));
}
matcher.appendTail(decodedMessage);
System.out.println(decodedMessage.toString());
于 2019-10-18T16:42:24.363 に答える
2

パフォーマンスが高く、エラー防止ソリューションを作成しました。

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();
}
于 2019-08-16T02:05:03.900 に答える
2

Java 9 以降では、 Matcherクラスの新しいreplaceAllメソッドを使用できます。

private static final Pattern UNICODE_PATTERN = Pattern.compile("\\\\u([0-9A-Fa-f]{4})");

public static String unescapeUnicode(String unescaped) {
    return UNICODE_PATTERN.matcher(unescaped).replaceAll(r -> String.valueOf((char) Integer.parseInt(r.group(1), 16)));
}

public static void main(String[] args) {
    String originalMessage = "\\u0048\\u0065\\u006C\\u006C\\u006F World";
    String unescapedMessage = unescapeUnicode(originalMessage);
    System.out.println(unescapedMessage);
}

StringEscapeUtilsによるunescapeJavaに対するこのアプローチの主な利点は(追加のライブラリを使用しないことに加えて)、Unicode 文字のみを変換できることです (必要に応じて)。後者はすべてのエスケープされた Java 文字 (\n や \t など) を変換するためです。 )。すべてのエスケープ文字を変換したい場合は、ライブラリが最適なオプションです。

于 2020-09-04T18:43:01.817 に答える
2

Kotlinを使用すると、 Stringの独自の拡張関数を作成できます。

fun String.unescapeUnicode() = replace("\\\\u([0-9A-Fa-f]{4})".toRegex()) {
    String(Character.toChars(it.groupValues[1].toInt(radix = 16)))
}

その後

fun main() {
    val originalString = "\\u0048\\u0065\\u006C\\u006C\\u006F World"
    println(originalString.unescapeUnicode())
}
于 2021-09-17T08:32:01.297 に答える