StringEscapeUtils не обрабатывает utf-8 - PullRequest
1 голос
/ 11 декабря 2019

У меня есть такая строка

String incoming = "<html> <head></head> <body>  <p><span style=\"font-family: Arial;\">Ευχαριστώ (eff-kha-ri-STOE) Tι κανείς (tee-KAH-nis)? Mε συγχωρείτε.</span></p> </body></html>";

, и я экранирую ее, используя StringEscapeUtils

import org.apache.commons.text.StringEscapeUtils;
String escaped = StringEscapeUtils.escapeJava(incoming);

В результате получается

<html> <head></head> <body>  <p><span style=\"font-family: Arial;\">\u0395\u03C5\u03C7\u03B1\u03C1\u03B9\u03C3\u03C4\u03CE (eff-kha-ri-STOE) T\u03B9 \u03BA\u03B1\u03BD\u03B5\u03AF\u03C2 (tee-KAH-nis)? M\u03B5 \u03C3\u03C5\u03B3\u03C7\u03C9\u03C1\u03B5\u03AF\u03C4\u03B5.</span></p> </body></html>

I 'мы пытались преобразовать его в utf-8, получая байты, и он не работает, есть ли способ, как это исправить?

вот что я попробовал:

String s = newString (escaped.getBytes ("UTF-8"), "UTF-8");

Я также пробовал использовать другую библиотеку, чтобы экранировать текст по-прежнему не получается.

1 Ответ

1 голос
/ 14 декабря 2019

Я предполагаю, что вы хотите, чтобы такие символы, как одинарные кавычки, двойные кавычки и обратная косая черта во входных данных String были экранированы, но вы хотите, чтобы греческие символы оставались неизменными.

К сожалению StringEscapeUtils.escapeJava() преобразует любые текстовые символы со значением Unicode> 0x7f в их эквиваленты Unicode Escape. Например, ваши примерные данные показывают, что греческая буква тау (τ) экранируется до \u03C4 в строке, возвращаемой StringEscapeUtils.escapeJava(). Я не знаю, почему escapeJava() делает это. В его Javadoc указано " Экранирует символы в строке, используя правила Java String. ", но я не смог найти формальное определение " Java String rules ".

Простой способ удалить экранирование Unicode в строке, возвращаемой StringEscapeUtils.escapeJava(), - это вызвать метод translate() для UnicodeUnescaper() class :

Переводит экранированные значения Unicode в форме \ u + \ d \ d \ d \ d обратно в Unicode. Он поддерживает несколько символов 'u' и будет работать с +.

или без него. Поэтому вызов UnicodeUnescaper.translate() вернет String, что:

  • Оставит сбежавшеесимволы в строке, такие как двойные кавычки, не тронуты.
  • Заменяет литералы Unicode их греческими эквивалентами символов. Например, \u03C4 будет изменено на τ.

Код прост. Использование ваших данных:

import org.apache.commons.text.StringEscapeUtils;
import org.apache.commons.text.translate.UnicodeUnescaper;

void convert() {
    String incoming = "<html> <head></head> <body>  <p><span style=\"font-family: Arial;\">Ευχαριστώ (eff-kha-ri-STOE) Tι κανείς (tee-KAH-nis)? Mε συγχωρείτε.</span></p> </body></html>";
    String escaped = StringEscapeUtils.escapeJava(incoming); 
    String greekChars = new UnicodeUnescaper().translate(escaped);

    System.out.println("incoming:   " + incoming); 
    System.out.println("escaped:    " + escaped);    // Quotes are escaped, and Greek characters are converted to Unicode escapes.
    System.out.println("greekChars: " + greekChars); // Quotes remain escaped, but Unicode escapes are converted back to Greek characters.
}

Это вывод из println() вызовов:

run:
incoming:   <html> <head></head> <body>  <p><span style="font-family: Arial;">Ευχαριστώ (eff-kha-ri-STOE) Tι κανείς (tee-KAH-nis)? Mε συγχωρείτε.</span></p> </body></html>
escaped:    <html> <head></head> <body>  <p><span style=\"font-family: Arial;\">\u0395\u03C5\u03C7\u03B1\u03C1\u03B9\u03C3\u03C4\u03CE (eff-kha-ri-STOE) T\u03B9 \u03BA\u03B1\u03BD\u03B5\u03AF\u03C2 (tee-KAH-nis)? M\u03B5 \u03C3\u03C5\u03B3\u03C7\u03C9\u03C1\u03B5\u03AF\u03C4\u03B5.</span></p> </body></html>
greekChars: <html> <head></head> <body>  <p><span style=\"font-family: Arial;\">Ευχαριστώ (eff-kha-ri-STOE) Tι κανείς (tee-KAH-nis)? Mε συγχωρείτε.</span></p> </body></html>
BUILD SUCCESSFUL (total time: 0 seconds)

Примечания:

  • Обязательно используйте пакет org.apache.commons.text.translate для UnicodeUnescaper. Старые устаревшие версии существуют в org.apache.commons.lang3.text.translate. Это ссылка на страницу загрузки для Apache Commons Text, в настоящее время версия 1.8.
  • Это не идеальное решение, потому что она вызывает UnicodeUnescaper.translate(), чтобы исправить беспорядок, созданныйStringEscapeUtils.escapeJava(). Могут быть и другие подходы, которые являются более чистыми (с использованием альтернативы StringEscapeUtils.escapeJava()), но, похоже, этот способ хорошо работает для ваших данных.
...