Перейти к основному содержимому

Регулярные выражения \s и \s+ в Java

· 3 мин. чтения

Задача: Наибольшая подстрока без повторений

Для заданной строки s, найдите длину наибольшей подстроки без повторяющихся символов. Подстрока — это непрерывная непустая последовательность символов внутри строки...

ANDROMEDA 42

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 .