replaceAll и обратные слэши

87
06 марта 2022, 05:50

Сегодня занимался в Java проблемой кавычек в SQL запросах (инъекция) и обнаружил, что чтобы после результата функции получить \', я должен написать следующее:

String key = entry.getKey().replaceAll("'", "\\\\\\\\\'");
/*Оригинальная строчка*/
UPDATE t1 SET A' = '1' WHERE A = 'firefly';
/*Результат функции*/
UPDATE t1 SET A\' = '1' WHERE A = 'firefly';

Если я напишу просто \\', по вернется простая '. Почему такое происходит? Я проверил с помощью System.out.println('\\');, где консоль мне вернула \, то есть верный результат.

Answer 1

Для простой замены одного конкретного символа на пару других регулярные выражения не требуются, используйте String#replace:

String result = text.replace("'", "\\'");

Если же всё-таки нужно заменить совпадение регулярного выражения каким-то буквальным текстом, без шаблонов, местозаполнителей, обратных ссылок и т.д. воспользуйтесь методом Matcher.quoteReplacement, который экранирует всё, что нужно в шаблоне замены (не путайте с Pattern.quote!):

String result = text.replaceAll("'", Matcher.quoteReplacement("\\'"));

Зачем нужно экранировать $ и \ в шаблоне замены? Эти символы используются для задания специальных конструкций в шаблоне замены. \ (буквальный символ, "\\" в строковом литерале Java) является экранирующим символом $, а $ с последующим за ним числом формирует обратную ссылку на значение соответствующей захватывающей подмаски.

Пример кода:

import java.util.regex.*; 
// ...
String dano = "UPDATE t1 SET A' = '1' WHERE A = 'firefly';";
System.out.println(dano.replace("'", "\\'")); 
// => UPDATE t1 SET A\' = \'1\' WHERE A = \'firefly\';
System.out.println(dano.replaceAll("'", Matcher.quoteReplacement("\\'")));
// => UPDATE t1 SET A\' = \'1\' WHERE A = \'firefly\';
Answer 2

Читай документацию

Note that backslashes (\) and dollar signs ($) in the replacement string may cause the results to be different than if it were being treated as a literal replacement string; see Matcher.replaceAll. Use Matcher.quoteReplacement(java.lang.String) to suppress the special meaning of these characters, if desired.

Документация replaceAll(java.lang.String, java.lang.String)

READ ALSO
как переназначить ссылку this

как переназначить ссылку this

Как сделать чтобы методе класса можно было перекинуть ссылку объекта на созданный новый объект

93
Как добавить несколько фрагментов в один контейнер?

Как добавить несколько фрагментов в один контейнер?

Пытаюсь добавить несколько фрагментов в один контейнер, но в результате получается так, как если бы добавлял без цикла первый фрагментГде...

80
Задача выполняется только один раз

Задача выполняется только один раз

Решил реализовать в коде обновление информации по API запросу через определенный интервал времениСразу по нажатию кнопки информация приходит...

93
Cортировка листа по фамилии в файле

Cортировка листа по фамилии в файле

Не могу разобраться как сортировать в файле по фамилии

234