«1. Обзор

Подстановка строк — это стандартная операция при обработке строк в Java.

Благодаря удобному методу replaceAll() в классе String мы можем легко выполнять подстановку строк с помощью регулярных выражений. Однако иногда выражения могут сбивать с толку, например, \\s и \\s+.

В этом коротком уроке мы рассмотрим разницу между двумя регулярными выражениями на примерах.

2. Разница между \\s и \\s+

Регулярное выражение \\s — это предопределенный класс символов. Он указывает на один символ пробела. Рассмотрим набор пробельных символов:

[ \t\n\x0B\f\r]

Знак плюс + — это жадный квантификатор, означающий один или несколько раз. Например, выражение X+ соответствует одному или нескольким символам X.

Следовательно, регулярное выражение \\s соответствует одному пробельному символу, а \\s+ соответствует одному или нескольким пробельным символам.

3. replaceAll() с непустой заменой

Мы узнали значения регулярных выражений \\s и \\s+.

Теперь давайте посмотрим, как метод replaceAll() по-разному ведет себя с этими двумя регулярными выражениями.

Мы будем использовать строку в качестве входного текста для всех примеров:

String INPUT_STR = "Text   With     Whitespaces!   ";

Попробуем передать \\s методу replaceAll() в качестве аргумента:

String result = INPUT_STR.replaceAll("\\s", "_");
assertEquals("Text___With_____Whitespaces!___", result);

Метод replaceAll() находит одиночные пробельные символы и заменяет каждое совпадение символом подчеркивания. У нас есть одиннадцать пробелов во входном тексте. Таким образом, произойдет одиннадцать замен.

Далее, давайте передадим регулярное выражение \\s+ в метод replaceAll():

String result = INPUT_STR.replaceAll("\\s+", "_");
assertEquals("Text_With_Whitespaces!_", result);

Из-за жадного квантификатора + метод replaceAll() будет сопоставлять самую длинную последовательность смежных пробельных символов и заменять каждое совпадение с подчеркиванием.

В нашем входном тексте у нас есть три последовательности смежных пробельных символов. Поэтому каждый из трех станет символом подчеркивания.

4. replaceAll() с пустой заменой

Другим распространенным применением метода replaceAll() является удаление совпадающих шаблонов из входного текста. Обычно мы делаем это, передавая пустую строку вместо метода.

Давайте посмотрим, что получится, если удалить пробельные символы с помощью метода replaceAll() с регулярным выражением \\s:

String result1 = INPUT_STR.replaceAll("\\s", "");
assertEquals("TextWithWhitespaces!", result1);

Теперь мы передадим другое регулярное выражение \\s+ в replaceAll () метод:

String result2 = INPUT_STR.replaceAll("\\s+", "");
assertEquals("TextWithWhitespaces!", result2);

Поскольку замена представляет собой пустую строку, два вызова replaceAll() дают один и тот же результат, даже если два регулярных выражения имеют разные значения:

assertEquals(result1, result2);

Если мы сравним два replaceAll(), тот, у которого есть \\s+, более эффективен. Это связано с тем, что он выполняет работу только с тремя заменами, в то время как вызов с \\s выполняет одиннадцать замен.

5. Заключение

В этой короткой статье мы узнали о регулярных выражениях \\s и \\s+.

Мы также видели, как метод replaceAll() по-разному ведет себя с двумя выражениями.

Как всегда, код доступен на GitHub.