Как убрать строковый литерал Java в Java?

Я обрабатываю некоторый исходный код Java с использованием Java. Я извлекаю строковые литералы и передаю их функции, принимающей строку. Проблема в том, что мне нужно передать неэкранированную версию String функции (то есть это означает преобразование \ n в новую строку, а \\ - в одну \ и т. Д.).

Есть ли внутри Java API функция, которая делает это? Если нет, могу ли я получить такую ​​функциональность из какой-нибудь библиотеки? Очевидно, компилятор Java должен выполнить это преобразование.

В случае, если кто-то хочет знать, я пытаюсь не запутывать строковые литералы в декомпилированных обфусцированных файлах Java.

68
задан Michael 12 February 2019 в 10:31
поделиться

2 ответа

Вы можете использовать метод 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.

Ссылки

48
ответ дан 24 November 2019 в 14:06
поделиться

См. это из http://commons.apache.org/lang/:

StringEscapeUtils

StringEscapeUtils.unescapeJava(String str)

10
ответ дан 24 November 2019 в 14:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: