如何将Unicode编码的字符串转换为字母串

Sha*_*nBL 63 java unicode encoding

我有一个Unicode编码的字符串\uXXXX,我想将它转换为常规字母(UTF-8).例如:

String myString = "\u0048\u0065\u006C\u006C\u006F World";
Run Code Online (Sandbox Code Playgroud)

应该成为

"Hello World"
Run Code Online (Sandbox Code Playgroud)

我知道当我打印它显示的字符串时Hello world.我的问题是我从Unix机器上的文件中读取文件名,然后我搜索它们.文件名使用Unicode编码,当我搜索文件时,我找不到它们,因为它搜索\uXXXX名称中的文件.

Ton*_*ony 76

阿帕奇共享郎 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
Run Code Online (Sandbox Code Playgroud)


Nom*_*Sim 37

技术上做:

String myString = "\u0048\u0065\u006C\u006C\u006F World";
Run Code Online (Sandbox Code Playgroud)

自动将其转换为"Hello World",所以我假设您正在读取某个文件中的字符串.为了将其转换为"Hello",您必须将文本解析为单独的unicode数字(取得\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
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢你的帮助!我还找到了另一个解决方案:String s = StringEscapeUtils.unescapeJava("\\ u20ac \\n"); 它做的工作! (2认同)
  • 尝试重新发明标准Java库提供的方法.只需检查纯实现/sf/answers/2748614501/ (2认同)

Ped*_*ito 23

您可以使用StringEscapeUtils阿帕奇共享郎,即:

String Title = StringEscapeUtils.unescapeJava("\u0048\u0065\u006C\u006C\u006F");
Run Code Online (Sandbox Code Playgroud)

  • 在build.gradle中添加dependacy之后:编译'commons-lang:commons-lang:2.6'以上工作正常. (4认同)

big*_*awn 16

字节编码和字符串

在java中用于转换字符串(String)中的字节流(byte [])并返回String类具有以下功能:

构造函数String (byte [] bytes, String enc)接收带有编码的输入字节流; 如果省略编码,默认情况下将接受

getBytes Method (String enc)返回以指定编码记录的字节流; 编码也可以省略.

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();
}
Run Code Online (Sandbox Code Playgroud)

更新:

从Java 1.7开始使用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);
Run Code Online (Sandbox Code Playgroud)

  • 这个答案使用`java.lang.String`提供的方法,它是专业的. (3认同)

Yev*_*ian 8

使用Kotlin,您可以为String编写自己的扩展函数

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

进而

fun main() {
    val originalString = "\\u0048\\u0065\\u006C\\u006C\\u006F World"
    println(originalString.unescapeUnicode())
}
Run Code Online (Sandbox Code Playgroud)


and*_*ate 7

这个简单的方法适用于大多数情况,但会跳过"u005Cu005C"这样的东西,它应该解码为字符串"\ u0048"但实际上会解码"H",因为第一遍产生"\ u0048"作为工作字符串然后由while循环再次处理.

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;
}
Run Code Online (Sandbox Code Playgroud)


ssu*_*ukk 7

较短的版本:

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;
}
Run Code Online (Sandbox Code Playgroud)


Bog*_*kyi 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>
Run Code Online (Sandbox Code Playgroud)

示例代码:

org.apache.commons.text.StringEscapeUtils.unescapeJava(escapedString);
Run Code Online (Sandbox Code Playgroud)


Mar*_*ros 5

对于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);
}
Run Code Online (Sandbox Code Playgroud)

我相信这种方法相对于StringEscapeUtilsunescapeJava的主要优点(除了不使用额外的库)是你只能转换 unicode 字符(如果你愿意的话),因为后者会转换所有转义的 Java 字符(如 \n 或 \t )。如果您希望转换所有转义字符,那么该库确实是最好的选择。