Пакет java.util.regex предоставляется Java с целью сопоставления регулярных выражений с шаблоном. Регулярные выражения Java характеризуются существенным сходством с языком программирования Perl и очень просты в освоении.

В Java регулярные выражения представляют собой особую последовательность символов, позволяющую вам сопоставить или выявить другие строки либо их набор, опираясь на специализированный синтаксис в качестве шаблона. Они могут быть использованы для поиска, редактирования либо манипулирования текстом и данными.

Пакет java.util.regex исходно состоит из следующих трех классов:

  • Pattern Class – объект класса Pattern представляет скомпилированное представление регулярного выражения. В классе Pattern публичный конструктор не предусмотрен. Для создания шаблона, вам сперва необходимо вызвать один из представленных публичных статичных методов compile(), который далее произведет возврат объекта класса Pattern. Регулярное выражение в данных методах принимается как первый аргумент.
  • Matcher Class – объект класса Matcher представляет механизм, который интерпретирует шаблон, а также производит операции сопоставления с вводимой строкой. Аналогично классу Pattern, Matcher не содержит публичных конструкторов. Объект класса Matcher может быть получен путем вызова метода matcher() на объекте класса Pattern.
  • PatternSyntaxException – объект класса PatternSyntaxException представляет непроверяемое исключение, которое обозначает синтаксическую ошибку в шаблоне регулярного выражения.

Группы сбора

Группы сбора представляют способ обращения с несколькими символами как с одной единицей. Они создаются путем размещения символов, которые предстоит сгруппировать, в серии круглых скобок. К примеру, регулярное выражение (dog) составляет отдельную группу, содержащую буквы "d", "o", и "g".

Группы сбора нумеруются посредством определения числа открывающих круглых скобок слева направо. Так, в выражении ((A)(B(C))) присутствуют четыре подобные группы:

  • ((A)(B(C)))
  • (A)
  • (B(C))
  • (C)

Для определения числа групп, представленных в выражении, вызвать метод groupCount на объекте класса matcher в Java. Метод groupCount извлекает число типа int, отображающее количество групп сбора, представленных в сопоставляемом шаблоне.

Также имеется специальная группа, группа 0, которая во всех случаях представляет выражение в полном виде. Данная группа не включается в сумму, представленную методом groupCount.

Пример

Ниже рассмотрен пример регулярного выражения в Java, иллюстрирующий способ выявления строки цифр в представленных буквенно-цифровых строках.

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   public static void main( String args[] ) {
      // Строка для сканирования, чтобы найти шаблон
      String str = "Крещение Руси произошло в 988 году! Не так ли?";
      String pattern = "(.*)(\\d+)(.*)";

      // Создание Pattern объекта
      Pattern r = Pattern.compile(pattern);

      // Создание matcher объекта
      Matcher m = r.matcher(str);
      if (m.find( )) {
         System.out.println("Найдено значение: " + m.group(0));
         System.out.println("Найдено значение: " + m.group(1));
         System.out.println("Найдено значение: " + m.group(2));
      }else {
         System.out.println("НЕ СОВПАДАЕТ");
      }
   }
}

В итоге будет получен следующий результат:

Найдено значение: Крещение Руси произошло в 988 году! Не так ли?
Найдено значение: Крещение Руси произошло в 98
Найдено значение: 8

Синтаксис регулярных выражений – символы

В Java регулярные выражения используют специальные символы. В следующей таблице представлены метасимволы доступные в синтаксисе регулярных выражений.

Подвыражение Обозначение символов
^ Соответствует началу строки.
$ Соответствует концу строки.
. Соответствует любому одиночному символу, за исключением новой строки. Использование опции m делает возможным соответствие новой строке.
[...] Соответствует любому одиночному символу в квадратных скобках.
[^...] Соответствует любому одиночному символу вне квадратных скобок.
\A Начало целой строки.
\z Конец целой строки.
\Z Конец целой строки, за исключением допустимого терминатора конца строки.
re* Соответствует 0 либо более вхождений предыдущего выражения.
re+ Соответствует 1 либо более вхождений предыдущего выражения.
re? Соответствует 0 либо 1 вхождению предыдущего выражения.
re{ n} Соответствует заданному n числу вхождений предыдущего выражения.
re{ n,} Соответствует n или большему числу вхождений предыдущего выражения.
re{ n, m} Соответствует n как минимум и m в большинстве вложений предыдущего выражения.
a| b Соответствует a или b.
(re) Группирует регулярные выражения и запоминает сравниваемый текст.
(?: re) Группирует регулярные выражения, не запоминая сравниваемый текст.
(?> re) Соответствует независимому шаблону без возврата.
\w Соответствует словесным символам.
\W Соответствует символам, не образующим слова.
\s Соответствует пробелу. Эквивалент [\t\n\r\f].
\S Соответствует непробельному символу.
\d Соответствует цифре. Эквивалент [0-9].
\D Соответствует нечисловому символу.
\A Соответствует началу строки.
\Z Соответствует окончанию строки. При наличии новой строки, располагается перед ней.
\z Соответствует концу строки.
\G Соответствует точке, где оканчивается предыдущее совпадение.
\n Обратная ссылка на группу сбора под номером "n".
\b Соответствует границе слова вне квадратных скобок. Соответствует возврату на одну позицию (0x08) внутри квадратных скобок.
\B Соответствуют границам символов, не образующих слова.
\n, \t, etc. Соответствует символам перевода строки, возврата каретки, табуляции, и т.д.
\Q Управление (цитирование) всех символов до символа \E.
\E Окончание цитаты, открытой при помощи \Q.

Методы класса Matcher

Далее представлен список полезных методов экземпляра класса.

Методы индексов

Методы индексов представляют полезные значения индекса, которые демонстрируют точное количество соответствий, обнаруженных в вводимой строке.

№. Метод и описание
1 public int start()
Возврат начального индекса к предыдущему совпадению.
2 public int start(int group)
Возврат начального индекса к последовательности, захваченной данной группой в течение предыдущей операции установления соответствия.
3 public int end()
Возврат позиции смещения следом за последним совпадающим символом.
4 public int end(int group)
Возврат позиции смещения следом за последним символом к последовательности, захваченной данной группой в течение предыдущей операции установления соответствия.

Методы исследования

Методы исследования производят анализ вводимой строки и возврат булевого значения, отображающего наличие либо отсутствие шаблона.

№. Метод и описание
1 public boolean lookingAt()
Предпринимает попытку поиска соответствия вводимой последовательности в начале области с шаблоном.
2 public boolean find()
Предпринимает попытку поиска следующей подпоследовательности в вводимой последовательности, соответствующей шаблону.
3 public boolean find(int start)
Сброс данного поиска соответствия и попытка поиска новой подпоследовательности в вводимой последовательности, соответствующей шаблону с указанного индекса.
4 public boolean matches()
Предпринимает попытку поиска совпадений во всей области с шаблоном.

Методы замены

Методы замены представляют полезные методы для замены текста в вводимой строке.

№. Метод и описание
1 public Matcher appendReplacement(StringBuffer sb, String replacement)
Производит нетерминальное присоединение и замену.
2 public StringBuffer appendTail(StringBuffer sb)
Производит терминальное присоединение и замену.
3 public String replaceAll(String replacement)
Заменяет каждую подпоследовательность в вводимой последовательности, совпадающей с шаблоном, указанным в замещающей строке.
4 public String replaceFirst(String replacement)
Замещает первую подпоследовательность в вводимой последовательности, совпадающей с шаблоном, указанным в замещающей строке.
5 public static String quoteReplacement(String s)
Возвращает литеральную замену Строки для указанной Строки. Данный метод производит сроку, которая будет функционировать в качестве литеральной замены s в методе appendReplacement класса Matcher.

Методы start и end

Далее представлен пример, в котором производится подсчет количества раз, когда в строке ввода встречается слово "кот".

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static final String REGEX = "\\bкот\\b";
   private static final String INPUT = "кот кот кот котёл кот";

   public static void main( String args[] ) {
      Pattern p = Pattern.compile(REGEX);
      Matcher m = p.matcher(INPUT);   // получение matcher объекта
      int count = 0;

      while(m.find()) {
         count++;
         System.out.println("Номер вхождения: "+count);
         System.out.println("Начальная позиция вхождения: "+m.start());
         System.out.println("Конечная позиция вхождения: "+m.end());
      }
   }
}

В итоге будет получен следующий результат:

Номер вхождения: 1
Начальная позиция вхождения: 0
Конечная позиция вхождения: 3
Номер вхождения: 2
Начальная позиция вхождения: 4
Конечная позиция вхождения: 7
Номер вхождения: 3
Начальная позиция вхождения: 8
Конечная позиция вхождения: 11
Номер вхождения: 4
Начальная позиция вхождения: 18
Конечная позиция вхождения: 21

Как видим, в данном примере используются границы слов с целью удостоверения в том, что буквы "c" "a" "t" не являются частью другого слова. Также отображаются определенные полезные сведения касательно нахождения совпадения в вводимой строке.

Метод start производит возврат начального индекса в последовательности, захваченной в данной группе в ходе предыдущей операции поиска совпадений, а end производит возврат индекса к последнему совпавшему символу, плюс один.

Методы matches и lookingAt

Оба метода matches и lookingAt направлены на попытку поиска соответствия вводимой последовательности с шаблоном. Разница, однако, заключается в том, что для метода matches требуется вся вводимая последовательность, в то время как lookingAt этого не требует.

Оба метода всегда начинаются в начале вводимой строки. Далее представлен пример, рассматривающий их функциональность.

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static final String REGEX = "Pro";
   private static final String INPUT = "ProgLang";
   private static Pattern pattern;
   private static Matcher matcher;

   public static void main( String args[] ) {
      pattern = Pattern.compile(REGEX);
      matcher = pattern.matcher(INPUT);

      System.out.println("Текущее регулярное выражение: " + REGEX);
      System.out.println("Текущие входные данные: " + INPUT);

      System.out.println("lookingAt(): " + matcher.lookingAt());
      System.out.println("matches(): " + matcher.matches());
   }
}

В итоге будет получен следующий результат:

Текущее регулярное выражение: Pro
Текущие входные данные: ProgLang
lookingAt(): true
matches(): false

Методы replaceFirst и replaceAll

Методы replaceFirst и replaceAll производят замену текста, который совпадает с заданным регулярным выражением. Исходя из их названия, replaceFirst производит замену первого совпадения, а replaceAll производит замену остальных совпадений.

Далее представлен пример, поясняющий их функциональность.

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static String REGEX = "Собака";
   private static String INPUT = "Собака говорит мяу.";
   private static String REPLACE = "Кот";

   public static void main(String[] args) {
      Pattern p = Pattern.compile(REGEX);
      
      // получение matcher объекта
      Matcher m = p.matcher(INPUT); 
      INPUT = m.replaceAll(REPLACE);
      System.out.println(INPUT);
   }
}

В итоге будет получен следующий результат:

Кот говорит мяу.

Методы appendReplacement и appendTail

Класс Matcher также предоставляет методы замены текста appendReplacement и appendTail.

Далее представлен пример, поясняющий их функциональность.

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static String REGEX = "а*д";
   private static String INPUT = "аадProgLangааадProgLangадProgLangд";
   private static String REPLACE = "-";
   public static void main(String[] args) {

      Pattern p = Pattern.compile(REGEX);
      
      // получение matcher объекта
      Matcher m = p.matcher(INPUT);
      StringBuffer sb = new StringBuffer();
      while(m.find()) {
         m.appendReplacement(sb, REPLACE);
      }
      m.appendTail(sb);
      System.out.println(sb.toString());
   }
}

В итоге будет получен следующий результат:

-ProgLang-ProgLang-ProgLang-

Методы класса PatternSyntaxException

PatternSyntaxException представляет непроверяемое исключение, которое отображает синтаксическую ошибку в шаблоне регулярного выражения. Класс PatternSyntaxException представлен следующими методами, которые помогут определить вам ошибку.

№.Метод и описание
1 public String getDescription()
Представляет описание ошибки.
2 public int getIndex()
Представляет индекс ошибки.
3 public String getPattern()
Представляет шаблон регулярного выражения, содержащего ошибку.
4 public String getMessage()
Производит возврат многострочной строки, содержащей описание синтаксической ошибки и ее индекс, ошибочный образец регулярного выражения, а также визуальную индикацию индекса ошибки в шаблоне.

Оглавление