2012-06-21 2 views
42

У меня есть строка с Unicode кодировкой, \uXXXX, и я хочу преобразовать ее в обычную букву (UTF-8). Например:Как преобразовать строку с кодировкой Unicode в строку букв

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

должен стать

"Hello World" 

Я знаю, что когда я печатаю строку он показывает Hello world. Моя проблема в том, что я читаю имена файлов из файла на компьютере Unix, а затем я их ищу. Имена файлов с кодировкой Unicode, и когда я ищу файлы, я не могу их найти, так как он ищет файл с именем \uXXXX.

+0

Вы уверены? Вы не думаете, что персонажи просто печатаются в качестве Unicode-экранов? –

+3

'\ u0048' * есть *' H' - они одно и то же. Строки в Java находятся в Юникоде. –

+0

Я думаю, проблема может быть в моей java для unix api - строка, которую я получаю, это что-то вроде этого: u3123 \ u3255_file_name.txt. И ява не скрывает его. – SharonBL

ответ

23

Технически делать:

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

автоматически преобразует его в "Hello World", поэтому я предполагаю, что вы читаете в строке из некоторого файла. Чтобы преобразовать его в «Привет», вам придется разобрать текст на отдельные цифры в Юникоде (возьмите \uXXXX и просто получите XXXX), затем сделайте Integer.ParseInt(XXXX, 16), чтобы получить шестнадцатеричное значение, а затем - char, чтобы получить фактическое персонаж.

Edit: Часть кода для достижения этой цели:

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 
+0

Кажется, это решение. У вас есть идея, как я могу это сделать в java - могу ли я сделать это с помощью String.replaceAll или что-то в этом роде? – SharonBL

+0

@SharonBL Я обновил код, должен хотя бы дать вам представление о том, с чего начать. – NominSim

+2

Спасибо вам большое за помощь! Я также нашел другое решение для этого: String s = StringEscapeUtils.unescapeJava ("\\ u20ac \\ n"); он делает работу! – SharonBL

4

Это не совсем ясно из вашего вопроса, но я предполагаю, что вы говорите, что у вас есть файл, где каждая строка этого файла является именем файла. И каждое имя файла что-то вроде этого:

\u0048\u0065\u006C\u006C\u006F 

Другими словами, символы в файле имен файлов \, u, 0, 0, 4, 8 и так далее.

Если да, то, что вы видите, ожидается. Java только переводит \uXXXX последовательности в строковых литералах в исходном коде (и при чтении в сохраненных объектах Properties). Когда вы читаете содержимое, файл, который вы будете иметь строку, состоящую из символов \, u, 0, 0, 4, 8 и так далее, и не строку Hello.

Так что вам нужно будет разобрать эту строку, чтобы извлечь 0048, 0065 и т.д. части, а затем преобразовать их в char с и сделать строку из этих char с, а затем передать эту строку в программе, которая открывает файл.

60

В Apache Commons LangStringEscapeUtils.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 
+0

Строка sJava = "\ u0048 \\ u006 \ u006C \ u006F"; -----> Пожалуйста, сделайте простое изменение. –

13

Вы можете использовать StringEscapeUtils из Apache Commons Lang, т.е.:

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

+2

после добавления зависимостей в build.gradle: compile 'commons-lang: commons-lang: 2.6' выше работающий хорошо. –

7

Этот простой метод будет работать для большинства случаев, но будет подножку на что-то вроде «u005Cu005C», который должен декодировать в строку «\ u0048», но фактически декодировать «H», как первый pass производит «\ 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; 
} 
+0

попытка повторного использования методов, предоставляемых стандартной библиотекой Java. просто проверьте чистую реализацию https://stackoverflow.com/a/39265921/1511077 –

3

попробовать

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

укороченная версия:

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; 
} 
+0

попытайтесь изобретать методы, предоставляемые стандартной библиотекой Java. просто проверьте чистую реализацию https://stackoverflow.com/a/39265921/1511077 –

1

один простой способ я знаю, используя JSONObject:

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

} catch (JSONException e) { 
    e.printStackTrace(); 
} 
6

Byte Encodings and Strings

В Java для преобразования потока байт (байт []) в строке (строка) и обратно к классу струнного имеет следующие особенности:

Конструктор 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(); 
} 
+1

В этом ответе используется метод, предоставляемый 'java.lang.String', и он является профессиональным. – Eddy

0

Фактически, я написал библиотеку с открытым исходным кодом, которая содержит некоторые утилиты. Один из них - преобразование последовательности Unicode в String и наоборот. Я нахожу это очень полезным. Вот цитата из статьи об этой библиотеке о конвертере Unicode:

Класс StringUnicodeEncoderDecoder имеет методы, которые могут превращающие строк (на любом языке) в последовательность символов Unicode и тиски-наоборот. Например, строка "Hello World" будет преобразован в

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

и могут быть восстановлены обратно.

Вот ссылка на всю статью, в которой объясняется, какие утилиты есть в библиотеке и как получить библиотеку для ее использования. Он доступен как артефакт Maven или как источник от Github. Он очень прост в использовании. Open Source Java library with stack trace filtering, Silent String parsing Unicode converter and Version comparison

0

Вот мое решение ...

   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

пытается переосмыслить стандартные методы, предоставляемые стандартной библиотекой Java. просто проверьте чистую реализацию https://stackoverflow.com/a/39265921/1511077 –

-1
public static String getEnglishText(String textWithUnicode){ 
     String word=""; 
     String newText= textWithUnicode; 
     int position=newText.indexOf("\\u"); 
     while(position!=-1) { 
     if(position!=0){ 
      word+=newText.substring(0,position); 
     } 
     String token=newText.substring(position+2,position+5); 
     newText=newText.substring(position+5); 
     word+=(char)Integer.parseInt(token); 
     position=newText.indexOf("\\u");} 
     word+=newText; 
     return word; 
    } 

Это работало на me.Check этого !!!

0

Раствор для Котлин:

val result = String(someText.toByteArray()) 

Котлин использует UTF-8 везде как кодировку по умолчанию

Кроме того, вы можете реализовать его в качестве расширения для класса Струнный:

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

, а затем используйте его просто:

val result = someText.unescape() 

;)

Смежные вопросы