Регулярные выражения в Java. Часть 1.

12-12-22 Java, Разное 1

В этой серии уроков мы научимся использовать java.util.regex API для регулярных выражений. Так же изучим синтаксис регулярных выражений.

Что такое регулярные выражения.

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

В данных уроках мы рассмотрим синтаксис регулярных выражений, а также примеры программ, работающих с java.util.regex API, чтобы понять как все это работает.

Как регулярные выражения представлены в Java?

Пакет  java.util.regex содержит три основных класса PatternMatcher, и PatternSyntaxException.

  • Объект Pattern  — это скомпилированное регулярное выражение. Pattern не предоставляет публичных конструкторов. Чтобы создать pattern необходимо вызвать public static compile метод, который вернет объект Pattern. Первый аргумент этой функции — регулярное выражение.
  • Объект Matcher — это «движок», который интерпретирует регулярное выражение и сопоставляет его с входной строкой. Как и класс PatternMatcher не имеет публичных конструкторов. Получить объект Matcher можно вызвав метод matcher объекта Pattern.
  • PatternSyntaxException — исключение, означающее синтаксическую ошибку в выражении.
В последствии мы рассмотрим подробно каждый из этих классов. Но сначала необходимо понимать, как устроены регулярные выражения. Рассмотрим тестовую программу для понимания синтаксиса регулярных выражений.
import java.io.Console;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class RegexTestHarness {

    public static void main(String[] args){
        Console console = System.console();
        if (console == null) {
            System.err.println("No console.");
            System.exit(1);
        }
        while (true) {

            Pattern pattern =
            Pattern.compile(console.readLine("%nEnter your regex: "));

            Matcher matcher =
            pattern.matcher(console.readLine("Enter input string to search: "));

            boolean found = false;
            while (matcher.find()) {
                console.format("I found the text" +
                    " \"%s\" starting at " +
                    "index %d and ending at index %d.%n",
                    matcher.group(),
                    matcher.start(),
                    matcher.end());
                found = true;
            }
            if(!found){
                console.format("No match found.%n");
            }
        }
    }
}

Создайте программу RegexTestHarness.java для изучения регулярных выражений. Команда для запуска программы:  java RegexTestHarness, можно без аргументов. Цикл программы повторяется, позволяя пользователя вводить регулярное выражение и строку для поиска. Вы можете не использовать данную программу, однако, она может быть полезна для тестирования примеров, которые мы будем рассматривать.

Строковые литералы

Основной задачей шаблонов является сравнение строк. Например, если регулярное выражение foo и входная строка foo, то программа найдет совпадение, потому что строки одинаковые. Попробуйте этот пример в нашей тестовой программе.

Enter your regex: foo
Enter input string to search: foo
I found the text foo starting at index 0 and ending at index 3.

Обратите внимание на то, что длина входной строки равна 3, начальный индекс 0, конечный 3:

Нумерация символов
Нумерация символов

Каждый символ строки расположен в своей ячейке с индексами, указывающими между ячеек. Строка foo начинается на индексе 0 и заканчивается на 3, несмотря на то, что занимает ячейки 0, 1, 2.

В следующем примере вы заметите некоторые особенности: следующее совпадение начинается там, где заканчивается предыдущее:

Enter your regex: foo
Enter input string to search: foofoofoo
I found the text foo starting at index 0 and ending at index 3.
I found the text foo starting at index 3 and ending at index 6.
I found the text foo starting at index 6 and ending at index 9.

Метасимволы

Данное API также поддерживает некоторый специальные символы, которые определяют «поведение» регулярного выражения. Попробуем изменить входную строку на cats, а регулярное выражение на cat. . Вывод:

Enter your regex: cat.
Enter input string to search: cats
I found the text cats starting at index 0 and ending at index 4.

Сравнение по-прежнему успешно, даже несмотря на точку во входной строке. Так произошло, потому что точка — метасимвол — специальный символ, который имеет какое-то значение для matcher’а. Метасимвол точка имеет смысл «любой символ», поэтому сравнение оказалось успешным в этом примере.

Метасимволы, поддерживаемые API: <([{\^-=$!|]})?*+.>

Существует два способа пометить метасимволы, чтобы они воспринимались как обычные:

  • экранировать метасимвол обратным слэшем
  • заключить в \Q (начало) и \E (конец).

Используя данный прием, вы можете поместить \Q и \E в любое место выражения, \Q необходимо располагать перед \E.
На этом все, в следующих уроках мы продолжим изучение регулярных выражений в Java.

Хочешь получать статьи на почту?

Подпишись на обновления!
* Ваш email не будет разглашен/продан. Вы сможете отписаться в любое время.

1 Комментарий

  1. Anatoly:

    Спасибо за доступное изложение материала, перехожу к следующей части.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *


+ два = 9