
Известно, что регулярные выражения – это, по сути, шаблоны из символов, которые задают определённое правило поиска. И, среди прочего, с их помощью возможно осуществить проверку определённой строки или строк на соответствие некоему заранее заданному паттерну или стандарту.
Одним из наглядных и довольно простых примеров использования регулярных выражений в Java и не только является проверка проверка данных пользователя, ввёдённых при регистрации на определённом сайте на корректность. В первую очередь это касается адреса электронной почты, так как к нему всегда предъявляются определённые орфографические требования.
Таким образом, предлагаю разобрать частный случай применения регулярных выражений на примере простого Java-приложения, которое могло бы обрабатывать введённый пользователем адрес электронной почты.
Итак, в Java все классы, описывающие регулярные выражения, хранятся в пакете java.util.regex. Нам понадобятся два класса – Pattern и Matcher
Первый класс, как видно из его названия, описывает паттерн или шаблон, которому должены соответствовать введённые нами данные (в нашем случае – адрес электронной почты), второй – собственно сами данные.
public class RegularExpression { public static void main(String [] args) { Pattern pattern = Pattern.compile(“”); Matcher matcher = pattern.matcher(“”); boolean matches = matcher.matches(); } }
С помощью класса Pattern создается объект, который возвращается статическим методом compile(). У данного метода нет конструкторов и передается в этот метод строка, которая, собственно, и будет нашим шаблоном. Кроме того, к классе Pattern предусмотрен метод matcher, в который по параметрам передается другая строка – та, которую мы хотим проверить на соответствие вышеуказанному шаблону. С помощью этого метода создается экземпляр класса Matcher.
У класса Matcher же, в свою очередь, имеется метод matches(), возвращающий true в случае соответствия данных паттерну и flase, если данные не прошли проверку. Результат мы запишем в булевую переменную matches.
Для того, чтобы перейти, собственно, к самой важной части – самому шаблону и его синтаксису, необходимо условиться о части требований предъявляемых к адресу электронной почты. В общем случае адрес электронной почты должен:
- Состоять из двух частей, разделённых символом “@”.
- Левая часть должна состоять из английских букв или цифр, может содержать точки и тире, притом после точки или тире обязательно должна следовать как минимум одна буква.
- Правая часть должна содержать хотя бы одну точку в конце, после которой должны следовать от двух до четырёх букв.
- Начинаться обе части должны с буквенных символов.
Начнём проверку с левой части. Она содержит буквенные символы в количестве от одной до бесконечности (на самом деле, конечно, количество их ограничено, но для наглядности представим себе потенциально бесконечный email). Синтаксисом регулярных выражений это описывается следующим образом:
Pattern pattern = Pattern.compile(“[A-Za-z0-9]{1,}”);
Символы в квадратных скобках указывают интервал возможных буквенных значений.
В фигурных скобках мы описываем допустимое количество символов, указанных ранее. Слева от запятой указано минимальное значение (единица), справа – максимальное. Отсутствие значения, как в нашем случае, говорит о том, что количество символов не имеет максимального значения. Паттерн также может содержать и строго фиксированное число символов или не содежать его вовсе. В последнем случае символ может быть использован лишь один раз.
Далее в нашем паттерне может быть знак тире. “Может быть” означает, что символ будет присутствовать в паттерне либо один раз, либо ни разу, следовательно:
Pattern pattern = Pattern.compile(“[A-Za-z0-9]){1,}[\\-]{0,1}”);
В случае присутствия тире, как мы уже оговорили, после него в обязательном порядке должна следовать хотя бы одна буква, т.е. начальный паттерн повторяется. Символ тире обозначается как [\\-]:
Pattern pattern = Pattern.compile(“[A-Za-z0-9]{1,}[\\-]{0,1}[A-Za-z0-9]{1,}”);
Помимо этого, в строке также может присутствовать точка ([\\.]), после которой, опять-таки, обязан следовать буквенный символ:
Pattern pattern = Pattern.compile(“[A-Za-z0-9]{1,}[\\-]{0,1}[A-Za-z0-9]{1,}[\\.]{0,1}[A-Za-z0-9]{1,}”);
Так как описанный паттерн левой части должен повторяться, мы обозначим это в следующем виде:
Pattern pattern = Pattern.compile(“([A-Za-z0-9]{1,}[\\-]{0,1}[A-Za-z0-9]{1,}[\\.]{0,1}[A-Za-z0-9]{1,})+”);
Знак плюса после общей скобки означает, что паттерн может повторяться от одного раза до неопределённого количества раз.
Так ка�� левую часть от правой отделяет собачка, мы указываем, что после левой части в обязательном порядке будет присутствовать этот символ:
Pattern pattern = Pattern.compile(“([A-Za-z0-9]{1,}[\\-]{0,1}[A-Za-z0-9]{1,}[\\.]{0,1}[A-Za-z0-9]{1,})+@”);
Правая часть паттерна должна содержать в себе уже упомянутый набор букв в количестве от одного до бесконечности с обязательным наличием точки в конце. Как и в предыдущем случае, паттерн до точки может повторяться:
Pattern pattern = Pattern.compile(“([A-Za-z0-9]{1,}[\\-]{0,1}[A-Za-z0-9]{1,}[\\.]{0,1}[A-Za-z0-9]{1,})+@([A-Za-z0-9]{1,}[\\-]{0,1}[A-Za-z0-9]{1,}[\\.]{0,1}[A-Za-z0-9]{1,})+[\\.]{1});
В конце паттерна должны вновь следовать символы, причём в количестве от двух до четырёх:
Pattern pattern = Pattern.compile(“([A-Za-z0-9]{1,}[\\-]{0,1}[A-Za-z0-9]{1,}[\\.]{0,1}[A-Za-z0-9]{1,})+@([A-Za-z0-9]{1,}[\\-]{0,1}[A-Za-z0-9]{1,}[\\.]{0,1}[A-Za-z0-9]{1,})+[\\.]{1}[a-z]{2,4}”);
Вот, собственно, и весь паттерн. Не маленький, не находите? К счастью, есть способ несколько сократить этот набор, сделав его более читабельным и лёгким для восприятия.
Для начала, существует способ одновременного выражения наличия тире или точки в паттерне. Вместо того, чтобы отдельно пропсывать все точки ([\\.]) и тире ([\\-]), их можно выразить единым символом — [\\.-]. Используя его, мы можем сократить паттерн до следующего:
Pattern pattern = Pattern.compile(“([A-Za-z0-9]{1,}[\\.-]{0,1}[A-Za-z0-9]{1,})+@([A-Za-z0-9]{1,}[\\.-]{0,1}[A-Za-z0-9]{1,})+[\\.]{1}[a-z]{2,4}”);
Также, существует символ, который может означать любую букву или цифру — \\w. Т.е. он способен заменить описание типа [A-Za-z0-9]:
Pattern pattern = Pattern.compile(“(\\w{1,}[\\.-]{0,1}\\w{1,})+@(\\w{1,}[\\.-]{0,1}\\w{1,})+[\\.]{1}[a-z]{2,4}”);
Так как знак плюса означает наличие символа в количестве от одного до бесконечности, описанное выше можно также свести до:
Pattern pattern = Pattern.compile(“(\\w+[\\.-]{0,1}\\w+)+@(\\w+[\\.-]{0,1}\\w+)+[\\.]{1}[a-z]{2,4}”);
Кроме того, наличие символа не более одного раза можно обозначить символом ?:
Pattern pattern = Pattern.compile(“(\\w+[\\.-]?\\w+)+@(\\w+[\\.-]?\\w+)+[\\.]{1}[a-z]{2,4}”);
Есть также символ, означающий наличие чего-либо в паттерне неопределённое количество раз, т.е. {0,}. Обозначается он как *. В итоговом варианте мы имеем следующее:
Pattern pattern = Pattern.compile(“\\w+([\\.-]?\\w+)*@\\w+([\\.-]?\\w+)*\\.\\w{2,4}”);
Подобный паттерн намного компактнее, чем то, к чему мы пришли ранее. Всё, что нам теперь остаётся – это реализовать формальную часть приложения, используя наш готовый паттерн и булевую переменную:
public class RegularExpression { public static void main(String [] args) { Pattern pattern = Pattern.compile(“\\w+([\\.-]?\\w+)*@\\w+([\\.-]?\\w+)*\\.\\w{2,4}”); Matcher matcher = pattern.matcher(“”); boolean matches = matcher.matches(); } }
Как именно использовать данную булевую переменную – это уже дело вкуса или возможностей. Ключевые же моменты уже готовы и дальнейшая доработка остаётся целиком за Вами.
Надеюсь, данное изожение было достаточно доступным. И конечно же, дерзайте.
