- Регулярное выражение Java проверяет примеры имен пользователей
- 1. Объяснение регулярного выражения имени пользователя
- 2. Регулярное выражение для проверки имени пользователя
- 3. Модульные тесты регулярных выражений имени пользователя
- 4. Антирегулярное выражение, средство проверки имени пользователя Java
- Скачать Исходный Код
- Рекомендации
- Java RegEx: использование регулярных выражений на практике
- Основы регулярных выражений
- Определение
- Синтаксис RegEx
- Квантификаторы
- Регулярные выражения в Java
- Экранирование символов в регулярных выражениях Java
- Ключевые классы
- Примеры использования регулярных выражений в Java
- e-mail адрес
- Телефонный номер
- IP адрес
- Правильное количество открытых и закрытых скобок в строке
- Извлечение даты
- Жадный режим
- Сверхжадный режим
- Ленивый режим
- Выводы
Регулярное выражение Java проверяет примеры имен пользователей
В этой статье показано, как использовать регулярное выражение для проверки имени пользователя в Java.
В этой статье показано, как использовать регулярное выражение для проверки имени пользователя в Java.
Требования к имени пользователя
- Имя пользователя состоит из буквенно-цифровых символов (a-za-Z0-9), строчных или прописных.
- Имя пользователя допускается с точкой (.), подчеркиванием (_) и дефисом (-).
- Точка (.), подчеркивание (_) или дефис (-) не должны быть первым или последним символом.
- Точка (.), подчеркивание (_) или дефис (-) не отображаются последовательно, например, java.. регулярное выражение
- Количество символов должно быть от 5 до 20.
Ниже приведено регулярное выражение, соответствующее всем вышеперечисленным требованиям.
1. Объяснение регулярного выражения имени пользователя
Ниже приведено объяснение регулярного выражения имени пользователя.
^[a-zA-Z0-9] # start with an alphanumeric character ( # start of (group 1) [._-](?![._-]) # follow by a dot, hyphen, or underscore, negative lookahead to # ensures dot, hyphen, and underscore does not appear consecutively | # or [a-zA-Z0-9] # an alphanumeric character ) # end of (group 1) # ensures the length of (group 1) between 3 and 18 [a-zA-Z0-9]$ # end with an alphanumeric character # plus the first and last alphanumeric characters, # total length became
Что такое?! Символ регулярного выражения ?! является негативным взглядом , гарантирует, что за чем-то не последует что-то другое; например, _(?!_) гарантирует, что подчеркивание не следует за подчеркиванием.
2. Регулярное выражение для проверки имени пользователя
Ниже приведен пример Java использования приведенного выше регулярного выражения для проверки имени пользователя.
package com.mkyong.regex.username; import java.util.regex.Matcher; import java.util.regex.Pattern; public class UsernameValidator < // simple regex //private static final String USERNAME_PATTERN = "^[a-z0-9\\._-]$"; // strict regex private static final String USERNAME_PATTERN = "^[a-zA-Z0-9]([._-](?![._-])|[a-zA-Z0-9])[a-zA-Z0-9]$"; private static final Pattern pattern = Pattern.compile(USERNAME_PATTERN); public static boolean isValid(final String username) < Matcher matcher = pattern.matcher(username); return matcher.matches(); >>
3. Модульные тесты регулярных выражений имени пользователя
Ниже приведены модульные тесты для проверки списка допустимых и недопустимых имен пользователей.
package com.mkyong.regex.username; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; public class UsernameValidatorTest < @ParameterizedTest(name = "#- Run test with username = ") @MethodSource("validUsernameProvider") void test_username_regex_valid(String username) < assertTrue(UsernameValidator.isValid(username)); >@ParameterizedTest(name = "# - Run test with username = ") @MethodSource("invalidUsernameProvider") void test_username_regex_invalid(String username) < assertFalse(UsernameValidator.isValid(username)); >static StreamvalidUsernameProvider() < return Stream.of( "mkyong", "javaregex", "JAVAregex", "java.regex", "java-regex", "java_regex", "java.regex.123", "java-regex-123", "java_regex_123", "javaregex123", "123456", "java123", "01234567890123456789"); >static Stream invalidUsernameProvider() < return Stream.of( "abc", // invalid length 3, length must between 5-20 "01234567890123456789a", // invalid length 21, length must between 5-20 "_javaregex_", // invalid start and last character ".javaregex.", // invalid start and last character "-javaregex-", // invalid start and last character "javaregex#$%@123", // invalid symbols, support dot, hyphen and underscore "java..regex", // dot cant appear consecutively "java--regex", // hyphen can't appear consecutively "java__regex", // underscore can't appear consecutively "java._regex", // dot and underscore can't appear consecutively "java.-regex", // dot and hyphen can't appear consecutively " ", // empty ""); // empty >>
4. Антирегулярное выражение, средство проверки имени пользователя Java
Ниже приведен эквивалентный Java-код для разработчиков антирегулярных выражений для проверки имени пользователя (соответствует всем вышеперечисленным требованиям к именам пользователей).
package com.mkyong.regex.username; public class UsernameValidatorCode < private static final char[] SUPPORT_SYMBOLS_CHAR = ; public static boolean isValid(final String username) < // check empty if (username == null || username.length() == 0) < return false; >// check length if (username.length() < 5 || username.length() >20) < return false; >return isValidUsername(username.toCharArray()); > private static boolean isValidUsername(final char[] username) < int currentPosition = 0; boolean valid = true; // check char by char for (char c : username) < // if alphanumeric char, no need check, process next if (!Character.isLetterOrDigit(c)) < // for non-alphanumeric char, also not a supported symbol, break if (!isSupportedSymbols(c)) < valid = false; break; >// ensures first and last char not a supported symbol if (username[0] == c || username[username.length - 1] == c) < valid = false; break; >// ensure supported symbol does not appear consecutively // is next position also a supported symbol? if (isSupportedSymbols(username[currentPosition + 1])) < valid = false; break; >> currentPosition++; > return valid; > private static boolean isSupportedSymbols(final char symbol) < for (char temp : SUPPORT_SYMBOLS_CHAR) < if (temp == symbol) < return true; >> return false; > >
Те же модульные тесты № 3 снова, замените средство проверки регулярных выражений указанным выше средством проверки имени пользователя Java, все тесты пройдены.
Дальнейшее чтение Если вы используете электронную почту в качестве имени пользователя, попробуйте сделать это Пример регулярного выражения электронной почты Java
Скачать Исходный Код
$cd java-регулярное выражение/имя пользователя
Рекомендации
- Википедия – Буквенно-цифровые обозначения
- Утверждения нулевой длины с регулярным выражением – Lookahead и Lookbehind
- Примеры регулярных выражений электронной почты Java
- Рекомендации по использованию Пароля и Имени пользователя
- JUnit 5 Параметризованные тесты
Java RegEx: использование регулярных выражений на практике
Рассмотрим регулярные выражения в Java, затронув синтаксис и наиболее популярные конструкции, а также продемонстрируем работу RegEx на примерах.
Основы регулярных выражений
Мы подробно разобрали базис в статье Регулярные выражения для новичков, поэтому здесь пробежимся по основам лишь вскользь.
Определение
Регулярные выражения представляют собой формальный язык поиска и редактирования подстрок в тексте. Допустим, нужно проверить на валидность e-mail адрес. Это проверка на наличие имени адреса, символа @ , домена, точки после него и доменной зоны.
Вот самая простая регулярка для такой проверки:
В коде регулярные выражения обычно обозначается как regex, regexp или RE.
Синтаксис RegEx
Символы могут быть буквами, цифрами и метасимволами, которые задают шаблон:
Есть и другие конструкции, с помощью которых можно сокращать регулярки:
- \d — соответствует любой одной цифре и заменяет собой выражение 4;
- \D — исключает все цифры и заменяет [^0-9];
- \w — заменяет любую цифру, букву, а также знак нижнего подчёркивания;
- \W — любой символ кроме латиницы, цифр или нижнего подчёркивания;
- \s — поиск символов пробела;
- \S — поиск любого непробельного символа.
Квантификаторы
Это специальные ограничители, с помощью которых определяется частота появления элемента — символа, группы символов, etc:
- ? — делает символ необязательным, означает 0 или 1 . То же самое, что и .
- * — 0 или более, .
- + — 1 или более, .
- — означает число в фигурных скобках.
- — не менее n и не более m раз.
- *? — символ ? после квантификатора делает его ленивым, чтобы найти наименьшее количество совпадений.
Примеры использования квантификаторов в регулярных выражениях
Обратите внимание, что квантификатор применяется только к символу, который стоит перед ним.
Также квантификаторов есть три режима:
"А.+а" //жадный режим — поиск самого длинного совпадения "А.++а" //сверхжадный режим — как жадный, но без реверсивного поиска при захвате строки "А.+?а" //ленивый режим — поиск самого короткого совпадения
По умолчанию квантификатор всегда работает в жадном режиме. Подробнее о квантификаторах в Java вы можете почитать здесь.
Примеры их использования рассмотрим чуть дальше.
Регулярные выражения в Java
Поскольку мы говорим о регекспах в Java, то следует учитывать спецификации данного языка программирования.
Экранирование символов в регулярных выражениях Java
В коде Java нередко можно встретить обратную косую черту \ : этот символ означает, что следующий за ним символ является специальным, и что его нужно особым образом интерпретировать. Так, \n означает перенос строки. Посмотрим на примере:
String s = "Это спецсимвол Java. \nОн означает перенос строки."; System.out.println(s);
Это спецсимвол Java. Он означает перенос строки.
Поэтому в регулярных выражениях для, например, метасимволов, используется двойная косая черта, чтобы указать компилятору Java, что это элемент регулярки. Пример записи поиска символов пробела:
Ключевые классы
Java RegExp обеспечиваются пакетом java.util.regex. Здесь ключевыми являются три класса:
- Matcher — выполняет операцию сопоставления в результате интерпретации шаблона.
- Pattern — предоставляет скомпилированное представление регулярного выражения.
- PatternSyntaxException — предоставляет непроверенное исключение, что указывает на синтаксическую ошибку, допущенную в шаблоне RegEx.
Также есть интерфейс MatchResult, который представляет результат операции сопоставления.
Примеры использования регулярных выражений в Java
e-mail адрес
В качестве первого примера мы упомянули регулярку, которая проверяет e-mail адрес на валидность. И вот как эта проверка выглядит в Java-коде:
List emails = new ArrayList(); emails.add("name@gmail.com"); //Неправильный имейл: emails.add("@gmail.com"); String regex = "^[A-Za-z0-9+_.-]+@(.+)$"; Pattern pattern = Pattern.compile(regex); for(String email : emails)
name@gmail.com : true @gmail.com : false
Телефонный номер
Регулярное выражение для валидации номера телефона:
Эта регулярка ориентирована на российские мобильные номера, а также на городские с кодом из трёх цифр. Попробуйте написать код самостоятельно по принципу проверки e-mail адреса.
IP адрес
А вот класс для определения валидности IP адреса, записанного в десятичном виде:
private static boolean checkIP(String input) < return input.matches("((0|1\\d|2(35|51))\\.)(0|1\\d|2(48|53))"); >
Правильное количество открытых и закрытых скобок в строке
На каждую открытую должна приходиться одна закрытая скобка:
private static boolean checkExpression(String input) < Pattern pattern = Pattern.compile("\\([\\d+/*-]*\\)"); Matcher matcher = pattern.matcher(input); do < input = matcher.replaceAll(""); matcher = pattern.matcher(input); >while (matcher.find()); return input.matches("[\\d+/*-]*"); >
Извлечение даты
Теперь давайте извлечём дату из строки:
private static String[] getDate(String desc) < int count = 0; String[] allMatches = new String[2]; Matcher m = Pattern.compile("(07|[12]9|3[01])[- /.](01|1[012])[- /.](19|20)\\d\\d").matcher(desc); while (m.find()) < allMatches[count] = m.group(); count++; >return allMatches; >
public static void main(String[] args) throws Exception< String[] dates = getDate("coming from the 25/11/2020 to the 30/11/2020"); System.out.println(dates[0]); System.out.println(dates[1]); >
А вот использование различных режимов квантификаторов, принцип работы которых мы рассмотрели чуть ранее.
Жадный режим
Pattern pattern = Pattern.compile("a+"); Matcher matcher = pattern .matcher("aaa"); while (matcher.find())
В заданном шаблоне первый символ – a . Matcher сопоставляет его с каждым символом текста, начиная с нулевой позиции и захватывая всю строку до конца, в чём и проявляется его «жадность». Вот и получается, что заданная стартовая позиция – это 0, а последняя – 2.
Сверхжадный режим
Pattern pattern = Pattern.compile("a++"); Matcher matcher = pattern .matcher("aaa"); while (matcher.find())
Принцип, как и в жадном режиме, только поиск заданного символа в обратном направлении не происходит. В приведённой строке всё аналогично: заданная стартовая позиция – это 0, а последняя – 2.
Ленивый режим
Pattern pattern = Pattern.compile("a+?"); Matcher matcher = pattern .matcher("aaa"); while (matcher.find())
Найдено от 0 дo 0 Найдено от 1 дo 1 Найдено от 2 дo 2
Здесь всё просто: самое короткое совпадение находится на первой, второй и третьей позиции заданной строки.
Выводы
Общий принцип использования регулярных выражений сохраняется от языка к языку, однако если мы всё-таки говорим о RegEx в конкретном языке программирования, следует учитывать его спецификации. В Java это экранирование символов, использование специальной библиотеки java.util.regex и её классов.
А какие примеры использования регулярных выражений в Java хотели бы видеть вы? Напишите в комментариях.