Я обрабатываю некоторый исходный код Java с использованием Java. Я извлекаю строковые литералы и передаю их функции, принимающей строку. Проблема в том, что мне нужно передать неэкранированную версию String функции (то есть это означает преобразование \ n
в новую строку, а \\
- в одну \
и т. Д.).
Есть ли внутри Java API функция, которая делает это? Если нет, могу ли я получить такую функциональность из какой-нибудь библиотеки? Очевидно, компилятор Java должен выполнить это преобразование.
В случае, если кто-то хочет знать, я пытаюсь не запутывать строковые литералы в декомпилированных обфусцированных файлах Java.
Вы можете использовать метод String unescapeJava (String)
из StringEscapeUtils
из Apache Commons Lang .
Вот пример фрагмента:
String in = "a\\tb\\n\\\"c\\\"";
System.out.println(in);
// a\tb\n\"c\"
String out = StringEscapeUtils.unescapeJava(in);
System.out.println(out);
// a b
// "c"
У служебного класса есть методы для экранирования и отмены экранирования строк для Java, Java Script, HTML, XML и SQL. Он также имеет перегрузку, которая записывает непосредственно в java.io.Writer
.
Похоже, что StringEscapeUtils
обрабатывает экранирование Unicode с помощью одного u
, но не восьмеричное экранирование, или экранирование Unicode с помощью посторонних u
s.
/* Unicode escape test #1: PASS */
System.out.println(
"\u0030"
); // 0
System.out.println(
StringEscapeUtils.unescapeJava("\\u0030")
); // 0
System.out.println(
"\u0030".equals(StringEscapeUtils.unescapeJava("\\u0030"))
); // true
/* Octal escape test: FAIL */
System.out.println(
"\45"
); // %
System.out.println(
StringEscapeUtils.unescapeJava("\\45")
); // 45
System.out.println(
"\45".equals(StringEscapeUtils.unescapeJava("\\45"))
); // false
/* Unicode escape test #2: FAIL */
System.out.println(
"\uu0030"
); // 0
System.out.println(
StringEscapeUtils.unescapeJava("\\uu0030")
); // throws NestableRuntimeException:
// Unable to parse unicode value: u003
Цитата из JLS:
Восьмеричные escape-последовательности предусмотрены для совместимости с C, но могут выражать только значения Unicode
\ u0000
-\ u00FF
, поэтому обычно используются escape-символы Unicode предпочтительнее.
Если ваша строка может содержать восьмеричные escape-последовательности, вы можете сначала преобразовать их в escape-символы Unicode или использовать другой подход.
Посторонний u
также задокументирован следующим образом:
Язык программирования Java определяет стандартный способ преобразования программы, написанной в Unicode, в ASCII, который преобразует программу в форму, которая может быть обработана Инструменты на основе ASCII. Преобразование включает преобразование любых escape-символов Unicode в исходном тексте программы в ASCII путем добавления дополнительного
u
- например,\ uxxxx
становится\ uuxxxx
- в то время как одновременное преобразование не-ASCII символов в исходном тексте в escape-последовательности Unicode, содержащие по одному u.Эта преобразованная версия одинаково приемлема для компилятора языка программирования Java и представляет собой ту же самую программу. Точный источник Unicode может быть позже восстановлен из этой формы ASCII путем преобразования каждой escape-последовательности, в которой присутствует несколько
u
, в последовательность символов Unicode с одним меньшимu
, при одновременном преобразовании каждая escape-последовательность с одиночнымu
к соответствующему одиночному символу Unicode.
Если ваша строка может содержать escape-последовательности Unicode с посторонними u
, вам также может потребоваться предварительная обработка перед использованием StringEscapeUtils
.
В качестве альтернативы вы можете попробовать написать свой собственный строковый литерал Java без экранирования с нуля, следя за точными спецификациями JLS.
См. это из http://commons.apache.org/lang/:
StringEscapeUtils.unescapeJava(String str)