admin 02 марта 2019

25 самых используемых регулярных выражений в Java

Список из 25 регулярных выражений в Java, без которых не обойтись ни новичку, ни профессиональному разработчику. С примерами.

Регулярные выражения в Java

Что такое Regex

Глупо спрашивать об очевидном, но вдруг вы новичок в сфере разработки? ;)

Регулярное выражение – это строка, последовательность символов. Данную строку также принято называть шаблоном, по которому происходит поиск соответствий в других последовательностях символов. Но не каждая строка компилируется в регулярное выражение, а только та, что соответствует их синтаксису.

25 самых используемых регулярных выражений в Java

Что за зверь "Pattern"?

Класс Java Pattern (java.util.regex.Pattern) является основной точкой доступа к API Java регулярных выражений. Всякий раз, когда требуется подключить Regex в работу, все начинается с Java-класса Pattern.

Java Pattern можно использовать двумя способами. Метод Pattern.matches() нужен для быстрой проверки соответствия текста заданному регулярному выражению. Так же можно скомпилировать экземпляр Pattern, используя Pattern.compile().  Его можно использовать несколько раз для сопоставления регулярного выражения с несколькими текстами.

☕ Подтянуть свои знания по Java вы можете на нашем телеграм-канале «Библиотека Java для собеса»


Что за зверь "Matcher"?

Класс Java Matcher (java.util.regex.Matcher) создан для поиска некоторого множества вхождений регулярного выражения в одном тексте и поиска по одному шаблону в разных текстах. Класс Java Matcher имеет много полезных методов.

Например:

  • boolean matches(): вернет значение true при совпадении строки с шаблоном.
  • boolean find(): вернет значение true при обнаружении подстроки, совпадающей с шаблоном, и перейдет к ней.
  • int start(): вернет значение индекса соответствия.
  • int end(): вернет значение индекса последующего соответствия.
  • String replaceAll(String str): вернет значение измененной строки подстрокой str.

Другие методы Matcher можно найти в официальной документации.

Рассмотрите простой пример работы с Pattern и Matcher.

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

public class Main {

public static void main (String[] args) {

Pattern pattern1 = Pattern.compile ("[x-z]+");//Поиск будет происходить от x до z включительно.
//Поиск будет происходить только по символам нижнего регистра.
//Чтобы отключить чувствительность к регистру, можно использовать Pattern.CASE_INSENSITIVE.

Matcher matcher1 = pattern1.matcher ("x y z 1 2 3 4 ");
System.out.println (matcher1.find()); //Поиск любого совпадения с шаблоном.
//Выводится значение true, так как в строке есть символы шаблона.

Matcher matcher2 = pattern1.matcher ("X Y Z 1 2 3 4");
System.out.println (matcher2.find()); //Выводится значение false.
//Так как в строке нет символов, подходящих по шаблону.

Pattern pattern2 = Pattern.compile ("[a-zA-Z0-9]");
//Добавляется поиск по символам нижнего и верхнего регистра, а также цифр.

Matcher matcher3 = pattern2.matcher ("A B C D X Y Z a b c d x y z 1 2 3 4");
System.out.println (matcher3.find()); //Выводится значение true

25 самых используемых регулярных выражений

.  Соответствие одиночному символу
^regex Поиск регулярного выражения с совпадением в начале строки
regex$ Поиск регулярного выражения с совпадением в конце строки
[abc] Поиск любого символа, заключенного в квадратные скобки
[abc][vz] Находит значение символа a, b или c, за  которыми следуют  v или z
[^ xyz] Когда символ  располагается перед остальными символами в квадратных скобках, он "отрицает" шаблон. Данный шаблон  соответствует любому символу, кроме x, y или z.
[a-d1-7] Диапазоны: соответствует букве между a  и d и цифрами от 1 до 7, но не d-1.
X|Z Находит X или Z
$ Конец строки
^ Начало строки
(re) Создает группу из регулярных выражений,  запоминая текст для сравнивания
(?: re) Действует как (re), но не запоминает текст

 

Следующие метасимволы имеют предопределенное значение и упрощают использование некоторых общих шаблонов, например, \d вместо [0..9].

Regex Значение
\d Любая цифра (эквивалентно [0-9])
\D Любой символ, кроме цифр
\s Символ пробела, сокращение от [\t \n  \x0b \r \f]
\S Любой символ, кроме пробела.
\w Символы, соответствующие словам, сокращение от [a-zA-Z_0-9]
\W Символы, не образующие слов, сокращение [\w]
\b Соответствует границе слова, где символом слова является [a-zA-Z0-9_]
\B Соответствует границам символов, не являющихся словами
\G Точка предыдущего соответствия

 

🧩☕ Интересные задачи по Java для практики можно найти на нашем телеграм-канале «Библиотека задач по Java»


Квантификаторы

Квантификатор определяет частоту появления элемента. Символы ?, *, + и {} определяют количество регулярных выражений:

Regex Значение Использование
* Происходит ноль или более раз, сокращенно {0,} X* не находит ни одной или нескольких букв X, <sbr/>.* Находит любую последовательность символов.
+ Происходит один или несколько раз, сокращенно {1,} X+  Находит одну или несколько букв X

 

? Не происходит  или происходт один раз,? является сокращением для {0,1}.

 

X? не находит ни одной буквы X или только одну.

 

{X} Происходит X раз \d{3} ищет три цифры.

 

{X,Y} Происходит не менее X, но не более Y раз \d{1,4} означает, что \d должно встречаться как минимум один раз и максимум четыре
*?

 

? после квантификатора делает его ленивым квантификатором. Он пытается найти наименьшее совпадение. Это останавливает регулярное выражение при первом совпадении.

 

 

Квантификаторы имеют три режима, которые называют сверхжадным, жадным и ленивым.

Жадный режим

“A.+a”// Ищет максимальное по длине совпадение в строке.

//Пример жадного квантификатора
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 
   
public class Main 
{ 
    public static void main(String[] args) 
    { 
         
        Pattern p = Pattern.compile("a+"); 
        Matcher m = p.matcher("aaa"); 
   
        while (m.find()) 
            System.out.println("Pattern found from " + m.start() + 
                               " to " + (m.end()-1)); 
   
    } 
}

Output:

Pattern found from 0 to 2

Сверхжадный режим

"А.++а"?// Работает также как и жадный режим, но не производит реверсивный поиск при захвате строки.

// Пример сверхжадного квантификатора
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 
   
public class Main 
{ 
    public static void main(String[] args) 
    {  
        Pattern p = Pattern.compile("a++"); 
        Matcher m = p.matcher("aaa"); 
   
        while (m.find()) 
            System.out.println("Pattern found from " + m.start() + 
                               " to " + (m.end()-1));  
    } 
}

Output:

Pattern found from 0 to 2

Ленивый режим

“A.+?a”// Ищет самое короткое совпадение.

//Пример ленивого квантификатора
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 
   
public class Main
{ 
    public static void main(String[] args) 
    { 
        Pattern p = Pattern.compile("g+?"); 
        Matcher m = p.matcher("ggg"); 
   
        while (m.find()) 
            System.out.println("Pattern found from " + m.start() + 
                               " to " + (m.end()-1)); 
   
    } 
}

Output:

Pattern found from 0 to 0
Pattern found from 1 to 1
Pattern found from 2 to 2

Профессиональные разработчики все время работают с регулярными выражениями. Перенимайте их практику: при частом использовании регулярки запомнятся быстро и существенно сэкономят время.

У вас случалось, что вы не можете вспомнить, что сами написали ранее? :) Следите, чтобы регулярные выражения комментировались в коде. Особенно это касается новых для вас регулярок. А если всё-таки запутаетесь, помогут сервисы для тестирования и отладки.

Хотите расширить диапазон нашего must-have списка? Пишите в комментариях, что бы вы добавили в наш ТОП.

Полезные материалы по теме:

Комментарии

ВАКАНСИИ

Добавить вакансию
Разработчик C++
Москва, по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ