1. Обзор
Регулярные выражения можно использовать для различных задач обработки текста, таких как алгоритмы подсчета слов или проверка ввода текста.
В этом руководстве мы рассмотрим, как использовать регулярные выражения для подсчета количества совпадений в некотором тексте .
2. Вариант использования
Давайте разработаем алгоритм, способный подсчитывать, сколько раз в строке появляется действительный адрес электронной почты .
Чтобы определить адрес электронной почты, мы будем использовать простой шаблон регулярного выражения:
([a-z0-9_.-]+)@([a-z0-9_.-]+[a-z])
Обратите внимание, что это тривиальный шаблон только для демонстрационных целей, поскольку фактическое регулярное выражение для сопоставления действительных адресов электронной почты довольно сложное.
Нам понадобится это регулярное выражение внутри объекта Pattern
, чтобы мы могли его использовать:
Pattern EMAIL_ADDRESS_PATTERN =
Pattern.compile("([a-z0-9_.-]+)@([a-z0-9_.-]+[a-z])");
Мы рассмотрим два основных подхода, один из которых зависит от использования Java 9 или более поздней версии.
Для нашего примера текста мы попытаемся найти три письма в строке:
"You can contact me through writer@foreach.com, editor@foreach.com, and team@bealdung.com"
3. Подсчет совпадений для Java 8 и старше
Во-первых, давайте посмотрим, как подсчитывать совпадения с использованием Java 8 или старше.
Простой способ подсчета совпадений состоит в повторении метода find
класса Matcher
. Этот метод пытается найти следующую подпоследовательность входной последовательности, которая соответствует шаблону :
Matcher countEmailMatcher = EMAIL_ADDRESS_PATTERN.matcher(TEXT_CONTAINING_EMAIL_ADDRESSES);
int count = 0;
while (countEmailMatcher.find()) {
count++;
}
Используя этот подход, мы найдем три совпадения, как и ожидалось:
assertEquals(3, count);
Обратите внимание, что метод find
не сбрасывает Matcher
после каждого найденного совпадения — он возобновляет работу с символа после окончания предыдущей совпавшей последовательности, поэтому поиск перекрывающихся адресов электронной почты не сработает.
Например, давайте рассмотрим этот пример:
String OVERLAPPING_EMAIL_ADDRESSES = "Try to contact us at team@foreach.comeditor@foreach.com, support@foreach.com.";
Matcher countOverlappingEmailsMatcher = EMAIL_ADDRESS_PATTERN.matcher(OVERLAPPING_EMAIL_ADDRESSES);
int count = 0;
while (countOverlappingEmailsMatcher.find()) {
count++;
}
assertEquals(2, count);
Когда регулярное выражение пытается найти совпадения в заданной строке ,
сначала оно найдет совпадение « team@foreach.comeditor ». Поскольку перед @ нет части домена, маркер не будет сброшен, а второй «@foreach.com»
будет проигнорирован. Двигаясь дальше, он также будет рассматривать « support@foreach.com » как второе совпадение:
Как показано выше, у нас есть только два совпадения в примере с перекрывающимся электронным письмом.
4. Подсчет совпадений для Java 9 и более поздних версий
Однако, если у нас есть более новая версия Java, мы можем использовать метод results
класса Matcher
. Этот метод, добавленный в Java 9, возвращает последовательный поток результатов совпадений, что упрощает подсчет совпадений:
long count = countEmailMatcher.results()
.count();
assertEquals(3, count);
Как мы видели с find
, Matcher
не сбрасывается при обработке потока из метода results .
Точно так же метод результатов
не будет работать для поиска перекрывающихся совпадений.
5. Вывод
В этой короткой статье мы узнали, как подсчитывать совпадения с регулярным выражением.
Во-первых, мы узнали, как использовать метод find
с циклом while
. Затем мы увидели, как новый метод потоковой передачи Java 9 позволяет нам делать это с меньшим количеством кода.
Как всегда, образцы кода доступны на GitHub .