Как работает метод replaceAll в Java и нужно ли использовать экранирование для точки в регулярном выражении
Что проверяют
Знаете ли вы, что replaceAll принимает регулярное выражение, а не обычную строку, и какие сюрпризы от этого бывают. Короткое «да, точку экранировать нужно» засчитают, но следом спросят, чем replaceAll отличается от replace и что особенного во втором аргументе.
Как отвечать
String.replaceAll(String regex, String replacement) равносилен Pattern.compile(regex).matcher(str).replaceAll(replacement). Точка в регулярном выражении означает любой символ, кроме перевода строки, поэтому "1.0.2".replaceAll(".", "-") вернёт "-----". Нужна буквальная точка, значит экранируем:
"\\.": регулярке нужен\., а в строковом литерале Java обратный слеш сам требует экранирования, отсюда два;"[.]": внутри символьного класса точка теряет спецсмысл, читается проще;Pattern.quote("."): оборачивает строку в\Q...\E, удобно, когда шаблон приходит извне.
Лучший ответ на задачу «заменить все точки» вообще без регулярки: str.replace(".", "-") или str.replace('.', '-'). Метод replace тоже заменяет все вхождения, только буквально, и в современных JDK не компилирует шаблон.
Отдельно про второй аргумент. В replacement особые символы $ и \: $1 подставляет группу, а одиночный $ приводит к IllegalArgumentException. Если строка замены пришла от пользователя, её пропускают через Matcher.quoteReplacement.
Про производительность: replaceAll компилирует шаблон при каждом вызове. В цикле или горячем методе Pattern выносят в поле static final и вызывают matcher(...).replaceAll(...).
Где спотыкаются
Думают, что replace заменяет только первое вхождение, а replaceAll все. Оба заменяют все, разница в том, регулярка ли первый аргумент. Первое совпадение по регулярке заменяет replaceFirst.
Пишут одиночный слеш "\.". Такой код не компилируется: \. не является допустимой escape-последовательностью в строке Java.
Попадают в ту же ловушку со split: "1.0.2".split(".") возвращает пустой массив, потому что разделителем стал каждый символ, а пустые строки в конце отбрасываются.