18. Java – Регулярные выражения
Пакет 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))) присутствуют четыре подобные группы:
Для определения числа групп, представленных в выражении, вызвать метод 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 числу вхождений предыдущего выражения. |
re | Соответствует n или большему числу вхождений предыдущего выражения. |
re | Соответствует 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() Производит возврат многострочной строки, содержащей описание синтаксической ошибки и ее индекс, ошибочный образец регулярного выражения, а также визуальную индикацию индекса ошибки в шаблоне. |
Оглавление
- 1. Java – Самоучитель для начинающих
- 2. Java – Обзор языка
- 3. Java – Установка и настройка
- 4. Java – Синтаксис
- 5. Java – Классы и объекты
- 6. Java – Конструкторы
- 7. Java – Типы данных и литералы
- 8. Java – Типы переменных
- 9. Java – Модификаторы
- 10. Java – Операторы
- 11. Java – Циклы и операторы цикла
- 11.1. Java – Цикл while
- 11.2. Java – Цикл for
- 11.3. Java – Улучшенный цикл for
- 11.4. Java – Цикл do..while
- 11.5. Java – Оператор break
- 11.6. Java – Оператор continue
- 12. Java – Операторы принятия решений
- 12.1. Java – Оператор if
- 12.2. Java – Оператор if..else
- 12.3. Java – Вложенный оператор if
- 12.4. Java – Оператор switch..case
- 12.5. Java – Условный оператор (? 🙂
- 13. Java – Числа
- 13.1. Java – Методы byteValue(), shortValue(), intValue(), longValue(), floatValue(), doubleValue()
- 13.2. Java – Метод compareTo()
- 13.3. Java – Метод equals()
- 13.4. Java – Метод valueOf()
- 13.5. Java – Метод toString()
- 13.6. Java – Метод parseInt()
- 13.7. Java – Метод Math.abs()
- 13.8. Java – Метод Math.ceil()
- 13.9. Java – Метод Math.floor()
- 13.10. Java – Метод Math.rint()
- 13.11. Java – Метод Math.round()
- 13.12. Java – Метод Math.min()
- 13.13. Java – Метод Math.max()
- 13.14. Java – Метод Math.exp()
- 13.15. Java – Метод Math.log()
- 13.16. Java – Метод Math.pow()
- 13.17. Java – Метод Math.sqrt()
- 13.18. Java – Метод Math.sin()
- 13.19. Java – Метод Math.cos()
- 13.20. Java – Метод Math.tan()
- 13.21. Java – Метод Math.asin()
- 13.22. Java – Метод Math.acos()
- 13.23. Java – Метод Math.atan()
- 13.24. Java – Метод Math.atan2()
- 13.25. Java – Метод Math.toDegrees()
- 13.26. Java – Метод Math.toRadians()
- 13.27. Java – Метод Math.random()
- 14. Java – Символы
- 14.1. Java – Метод Character.isLetter()
- 14.2. Java – Метод Character.isDigit()
- 14.3. Java – Метод Character.isWhitespace()
- 14.4. Java – Метод Character.isUpperCase()
- 14.5. Java – Метод Character.isLowerCase()
- 14.6. Java – Метод Character.toUpperCase()
- 14.7. Java – Метод Character.toLowerCase()
- 14.8. Java – Метод Character.toString()
- 15. Java – Строки
- 15.1. Java – Метод charAt()
- 15.2. Java – Метод compareTo()
- 15.3. Java – Метод compareToIgnoreCase()
- 15.4. Java – Метод concat()
- 15.5. Java – Метод contentEquals()
- 15.6. Java – Метод copyValueOf()
- 15.7. Java – Метод endsWith()
- 15.8. Java – Метод equals()
- 15.9. Java – Метод equalsIgnoreCase()
- 15.10. Java – Метод getBytes()
- 15.11. Java – Метод getChars()
- 15.12. Java – Метод hashCode()
- 15.13. Java – Метод indexOf()
- 15.14. Java – Метод intern()
- 15.15. Java – Метод lastIndexOf()
- 15.16. Java – Метод length()
- 15.17. Java – Метод matches()
- 15.18. Java – Метод regionMatches()
- 15.19. Java – Метод replace()
- 15.20. Java – Метод replaceAll()
- 15.21. Java – Метод replaceFirst()
- 15.22. Java – Метод split()
- 15.23. Java – Метод startsWith()
- 15.24. Java – Метод subSequence()
- 15.25. Java – Метод substring()
- 15.26. Java – Метод toCharArray()
- 15.27. Java – Метод toLowerCase()
- 15.28. Java – Метод toString()
- 15.29. Java – Метод toUpperCase()
- 15.30. Java – Метод trim()
- 15.31. Java – Метод valueOf()
- 15.32. Java – Классы StringBuilder и StringBuffer
- 15.32.1. Java – Метод append()
- 15.32.2. Java – Метод reverse()
- 15.32.3. Java – Метод delete()
- 15.32.4. Java – Метод insert()
- 15.32.5. Java – Метод replace()
- 16. Java – Массивы
- 17. Java – Дата и время
- 18. Java – Регулярные выражения
- 19. Java – Методы
- 20. Java – Потоки ввода/вывода, файлы и каталоги
- 20.1. Java – Класс ByteArrayInputStream
- 20.2. Java – Класс DataInputStream
- 20.3. Java – Класс ByteArrayOutputStream
- 20.4. Java – Класс DataOutputStream
- 20.5. Java – Класс File
- 20.6. Java – Класс FileReader
- 20.7. Java – Класс FileWriter
- 21. Java – Исключения
- 21.1. Java – Встроенные исключения
- 22. Java – Вложенные и внутренние классы
- 23. Java – Наследование
- 24. Java – Переопределение
- 25. Java – Полиморфизм
- 26. Java – Абстракция
- 27. Java – Инкапсуляция
- 28. Java – Интерфейсы
- 29. Java – Пакеты
- 30. Java – Структуры данных
- 30.1. Java – Интерфейс Enumeration
- 30.2. Java – Класс BitSet
- 30.3. Java – Класс Vector
- 30.4. Java – Класс Stack
- 30.5. Java – Класс Dictionary
- 30.6. Java – Класс Hashtable
- 30.7. Java – Класс Properties
- 31. Java – Коллекции
- 31.1. Java – Интерфейс Collection
- 31.2. Java – Интерфейс List
- 31.3. Java – Интерфейс Set
- 31.4. Java – Интерфейс SortedSet
- 31.5. Java – Интерфейс Map
- 31.6. Java – Интерфейс Map.Entry
- 31.7. Java – Интерфейс SortedMap
- 31.8. Java – Класс LinkedList
- 31.9. Java – Класс ArrayList
- 31.10. Java – Класс HashSet
- 31.11. Java – Класс LinkedHashSet
- 31.12. Java – Класс TreeSet
- 31.13. Java – Класс HashMap
- 31.14. Java – Класс TreeMap
- 31.15. Java – Класс WeakHashMap
- 31.16. Java – Класс LinkedHashMap
- 31.17. Java – Класс IdentityHashMap
- 31.18. Java – Алгоритмы Collection
- 31.19. Java – Iterator и ListIterator
- 31.20. Java – Comparator
- 32. Java – Дженерики
- 33. Java – Сериализация
- 34. Java – Сеть
- 34.1. Java – Обработка URL
- 35. Java – Отправка Email
- 36. Java – Многопоточность
- 36.1. Java – Синхронизация потоков
- 36.2. Java – Межпоточная связь
- 36.3. Java – Взаимная блокировка потоков
- 36.4. Java – Управление потоками
- 37. Java – Основы работы с апплетами
- 38. Java – Javadoc
Java Matcher find is false but matches is true [закрыт]
Вопрос вызван проблемой, которая больше не воспроизводится, или опечаткой. Хотя похожие вопросы могут быть уместны на этом сайте, решение для этого вопроса вряд ли поможет будущим посетителям. Обычно можно избежать подобных вопросов написанием и исследованием минимальной программы для воспроизведения проблемы до публикации вопроса.
Закрыт 1 год назад .
Я попытался разобрать строку с помощью регулярного выражения, но столкнулся с каким-то странным поведением
System.out.println(m.matches()); //returns true System.out.println(m.find()); //returns false
Похоже, у меня есть несколько ошибок в моем регулярном выражении. Весь код приведен ниже
import java.util.regex.Matcher; import java.util.regex.Pattern; public class testRegexp < public static void main(String[] args) < String string = "Alexandr TheMakedonian 32"; Pattern pattern = Pattern.compile("(.*)\\s(.*)\\s(.*)"); Matcher m = pattern.matcher(string); System.out.println(m.matches()); System.out.println(m.find()); System.out.println(m.groupCount()); if( m.find() && m.groupCount() >= 3) < String firstName = m.group(1); String secondName = m.group(2); String ages = m.group(3); System.out.println(firstName); System.out.println(secondName); System.out.println(ages); >> >
Отслеживать
Serg Sergy
задан 20 июн 2022 в 15:29
Serg Sergy Serg Sergy
9 3 3 бронзовых знака
Please translate your question to the Russian language, because this segment of SO is for the Russian-speaking people
20 июн 2022 в 15:31
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Вызов String.matches() сравнивает целую строку с шаблоном и после этого позиция для нового поиска перемещается в конец и соответственно последующий вызов find вернёт false , так как будет сравниваться пустая строка с шаблоном, в котором есть как минимум два пробела.
Если к примеру переставить вызовы данных методов местами или «сбросить» поиск при помощи Matcher::reset , оба вызова вернут true :
System.out.println(m.find()); // true System.out.println(m.matches()); // true Matcher m1 = pattern.matcher(string); System.out.println(m1.matches()); // true m1.reset(); System.out.println(m1.find()); // true
Matcher find java как работает
Регулярные выражения представляют мощный инструмент для обработки строк. Регулярные выражения позволяют задать шаблон, которому должна соответствовать строка или подстрока.
Некоторые методы класса String принимают регулярные выражения и используют их для выполнения операций над строками.
split
Для разделения строки на подстроки применяется метод split() . В качестве параметра он может принимать регулярное выражение, которое представляет критерий разделения строки.
Например, разделим предложение на слова:
String text = «FIFA will never regret it»; String[] words = text.split(«\\s*(\\s|,|!|\\.)\\s*»); for(String word : words)
Для разделения применяется регулярное выражение «\\s*(\\s|,|!|\\.)\\s*». Подвыражние «\\s» по сути представляет пробел. Звездочка указывает, что символ может присутствовать от 0 до бесконечного количества раз. То есть добавляем звездочку и мы получаем неопределенное количество идущих подряд пробелов — «\\s*» (то есть неважно, сколько пробелов между словами). Причем пробелы может вообще не быть. В скобках указывает группа выражений, которая может идти после неопределенного количества пробелов. Группа позволяет нам определить набо значений через вертикальную черту, и подстрока должна соответствовать одному из этих значений. То есть в группе «\\s|,|!|\\.» подстрока может соответствовать пробелу, запятой, восклицательному знаку или точке. Причем поскольку точка представляет специальную последовательность, то, чтобы указать, что мы имеем в виду имеено знак точки, а не специальную последовательность, перед точкой ставим слеши.
Соответствие строки. matches
Еще один метод класса String — matches() принимает регулярное выражение и возвращает true, если строка соответствует этому выражению. Иначе возвращает false.
Например, проверим, соответствует ли строка номеру телефона:
String input = «+12343454556»; boolean result = input.matches(«(\\+*)\\d»); if(result) < System.out.println("It is a phone number"); >else
В данном случае в регулярном выражение сначала определяется группа «(\\+*)». То есть вначале может идти знак плюса, но также он может отсутствовать. Далее смотрим, соответствуют ли последующие 11 символов цифрам. Выражение «\\d» представляет цифровой символ, а число в фигурных скобках — — сколько раз данный тип символов должен повторяться. То есть мы ищем строку, где вначале может идти знак плюс (или он может отсутствовать), а потом идет 11 цифровых символов.
Класс Pattern
Большая часть функциональности по работе с регулярными выражениями в Java сосредоточена в пакете java.util.regex .
Само регулярное выражение представляет шаблон для поиска совпадений в строке. Для задания подобного шаблона и поиска подстрок в строке, которые удовлетворяют данному шаблону, в Java определены классы Pattern и Matcher .
Для простого поиска соответствий в классе Pattern определен статический метод boolean matches(String pattern, CharSequence input) . Данный метод возвращает true, если последовательность символов input полностью соответствует шаблону строки pattern:
import java.util.regex.Pattern; public class StringsApp < public static void main(String[] args) < String input = "Hello"; boolean found = Pattern.matches("Hello", input); if(found) System.out.println("Найдено"); else System.out.println("Не найдено"); >>
Но, как правило, для поиска соответствий применяется другой способ — использование класса Matcher.
Класс Matcher
Рассмотрим основные методы класса Matcher:
- boolean matches() : возвращает true, если вся строка совпадает с шаблоном
- boolean find() : возвращает true, если в строке есть подстрока, которая совпадает с шаблоном, и переходит к этой подстроке
- String group() : возвращает подстроку, которая совпала с шаблоном в результате вызова метода find. Если совпадение отсутствует, то метод генерирует исключение IllegalStateException .
- int start() : возвращает индекс текущего совпадения
- int end() : возвращает индекс следующего совпадения после текущего
- String replaceAll(String str) : заменяет все найденные совпадения подстрокой str и возвращает измененную строку с учетом замен
Используем класс Matcher. Для этого вначале надо создать объект Pattern с помощью статического метода compile() , который позволяет установить шаблон:
Pattern pattern = Pattern.compile("Hello");
В качестве шаблона выступает строка «Hello». Метод compile() возвращает объект Pattern, который мы затем можем использовать в программе.
В классе Pattern также определен метод matcher(String input) , который в качестве параметра принимает строку, где надо проводить поиск, и возвращает объект Matcher :
String input = "Hello world! Hello Java!"; Pattern pattern = Pattern.compile("hello"); Matcher matcher = pattern.matcher(input);
Затем у объекта Matcher вызывается метод matches() для поиска соответствий шаблону в тексте:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class StringsApp < public static void main(String[] args) < String input = "Hello"; Pattern pattern = Pattern.compile("Hello"); Matcher matcher = pattern.matcher(input); boolean found = matcher.matches(); if(found) System.out.println("Найдено"); else System.out.println("Не найдено"); >>
Рассмотрим более функциональный пример с нахождением не полного соответствия, а отдельных совпадений в строке:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class StringsApp < public static void main(String[] args) < String input = "Hello Java! Hello JavaScript! JavaSE 8."; Pattern pattern = Pattern.compile("Java(\\w*)"); Matcher matcher = pattern.matcher(input); while(matcher.find()) System.out.println(matcher.group()); >>
Допустим, мы хотим найти в строке все вхождения слова Java. В исходной строке это три слова: «Java», «JavaScript» и «JavaSE». Для этого применим шаблон «Java(\\w*)». Данный шаблон использует синтаксис регулярных выражений. Слово «Java» в начале говорит о том, что все совпадения в строке должны начинаться на Java. Выражение (\\w*) означает, что после «Java» в совпадении может находиться любое количество алфавитно-цифровых символов. Выражение \w означает алфавитно-цифровой символ, а звездочка после выражения указывает на неопределенное их количество — их может быть один, два, три или вообще не быть. И чтобы java не рассматривала \w как эскейп-последовательность, как \n, то выражение экранируется еще одним слешем.
Далее применяется метод find() класса Matcher, который позволяет переходить к следующему совпадению в строке. То есть первый вызов этого метода найдет первое совпадение в строке, второй вызов найдет второе совпадение и т.д. То есть с помощью цикла while(matcher.find()) мы можем пройтись по всем совпадениям. Каждое совпадение мы можем получить с помощью метода matcher.group() . В итоге программа выдаст следующий результат:
Java JavaScript JavaSE
Замена в строке
Теперь сделаем замену всех совпадений с помощью метода replaceAll() :
String input = "Hello Java! Hello JavaScript! JavaSE 8."; Pattern pattern = Pattern.compile("Java(\\w*)"); Matcher matcher = pattern.matcher(input); String newStr = matcher.replaceAll("HTML"); System.out.println(newStr); // Hello HTML! Hello HTML! HTML 8.
Также надо отметить, что в классе String также имеется метод replaceAll() с подобным действием:
String input = "Hello Java! Hello JavaScript! JavaSE 8."; String myStr =input.replaceAll("Java(\\w*)", "HTML"); System.out.println(myStr); // Hello HTML! Hello HTML! HTML 8.
Разделение строки на лексемы
С помощью метода String[] split(CharSequence input) класса Pattern можно разделить строку на массив подстрок по определенному разделителю. Например, мы хотим выделить из строки отдельные слова:
import java.util.regex.Pattern; public class StringsApp < public static void main(String[] args) < String input = "Hello Java! Hello JavaScript! JavaSE 8."; Pattern pattern = Pattern.compile("[ . ]"); String[] words = pattern.split(input); for(String word:words) System.out.println(word); >>
И консоль выведет набор слов:
Hello Java Hello JavaScript JavaSE 8
При этом все символы-разделители удаляются. Однако, данный способ разбивки не идеален: у нас остаются некоторые пробелы, которые расцениваются как лексемы, а не как разделители. Для более точной и изощренной разбивки нам следует применять элементы регулярных выражений. Так, заменим шаблон на следующий:
Pattern pattern = Pattern.compile("\\s*(\\s|,|!|\\.)\\s*");
Теперь у нас останутся только слова:
Hello Java Hello JavaScript JavaSE 8
Далее мы подробнее рассмотрим синтаксис регулярных выражений и из каких элементов мы можем создавать шаблоны.
Руководство по Java. Регулярные выражения Java.
Регулярные выражения – это специальные последовательности символов, которые помогают нам находить строки или множества строк, используя специальные синтаксические шаблоны.
Регулярные выражения в Java обеспечиваются пакетом java.util.regex.
В пакете java.util.regex ключевыми являются 3 класса:
- Matcher
Этот класс интерпретирует шаблон и определяет совпадения в водимой строке. - Pattern
Класс Pattern предоставляет нам скомпилированный вариант регулярного выражения. - PatternSyntaxException
Этот класс предоставляет нам непроверяемые исключения, которые указывают нам на синтаксическую ошибку в нашем регулярном выражении.
Схватывающая группа
Схватывающая группа – это способ представить несколько символов, как единый элемент. Они создаются путём размещения символов внутри множества скобок. Например, слово (car) создаёт единую группу, которая состоит из букв “c”, “a” и “r”.
Для того чтобы понять, как это применяется на практике, рассмотрим пример простого приложения.
import java.util.regex.Matcher; import java.util.regex.Pattern; public class CapturingGroupDemo < public static void main(String[] args) < String inputString = "This is simple that contains phone number +380505055050 That's great."; String pattern = "(\\d+)"; Pattern ptrn = Pattern.compile(pattern); Matcher matcher = ptrn.matcher(inputString); if(matcher.find())< System.out.println("Phone number: " + matcher.group(0)); >else < System.out.println("PHONE NUMBER NOT FOUND"); >> >
В результате работы программы мы получим такой результат:
/*Some system messages*/ Phone number: 380505055050
Здесь приведён крайне примитивный способ найти номер телефона в строке. На практике, для такой операции понадобиться более сложный шаблон, но в качестве примера нас устроит и такой вариант.
Как мы видим, мы применяем регулярное выражение \d, которое выводит числа (от 0 до 9). В результате программа опускает все нечисловые символы в строке и возвращает нам только номер телефона.
Ниже приведён список символов, которые мы можем использовать для регулярных выражений в языке программирования Java.
^ | Совпадает начало строки |
$ | Совпадает конец строки |
. | Совпадают все символы, кроме символа новой строки. |
[…] | Совпадает любой отдельный символ в скобках. |
[^…] | Совпадает любой отдельный символ не в скобках. |
\A | Начало всей строки |
\z | Конец всей строки |
\Z | Конец всей строки, за исключением допустимого конечного конца строки. |
re* | Совпадает 0 или более вхождений предыдущего выражения. |
re+ | Совпадает 1 или более из предыдущих вещей. |
re? | Совпадает 0 или 1 вхождений предыдущего выражения. |
re | Совпадает n вхождений предыдущего выражения. |
re | Совпадает n или более вхождений предыдущего выражения. |
re | Совпадает от n до m вхождений предыдущего выражения. |
a| b | Совпадает a или b. |
(re) | Группирует регулярные выражения и запоминает совпадающий текст. |
(?: re) | Группирует регулярные выражения без запоминания совпадающего текста. |
(?> re) | Совпадает независимый шаблон без возвратов. |
\w | Совпадает символ в слове. |
\W | Совпадает символ не в слове. |
\s | Совпадают пробелы. |
\S | Совпадают не пробелы. |
\d | Совпадают числа. |
\D | Совпадают не числа. |
\G | Соответствует точке, где заканчивается предыдущее совпадение. |
\n | Обратная ссылка для захвата числа n. |
\b | Совпадают границы слова за пределами скобок. |
\B | Совпадают границы не слова. |
\n, \t, etc. | Совпадают соответствующие символы (новая строка, возврат каретки и т.д.) |
\Q | Цитаты, до символа \Е |
\E | Конец цитаты \Q |
Методы класса Matcher
В классе Matcher есть ряд методов, для определения места совпадения.
- public int start()
Возвращает начальный индекс предыдущего совпадения. - public int start(int group)
Возвращает начальный индекс подстроки, захваченной данной группой во время предыдущего совпадения. - public int end()
Возвращает смещение после крайнего совпадающего символа. - public int end(int group)
Возвращает смещение после крайнего символа подстроки, захваченного данной группой во время крайнего совпадения.
Методы поиска
Методы поиска предназначены для того, чтобы узнать есть ли во вводимой строке указанный шаблон (pattern).
Вот список методов поиска:
- public boolean lookingAt()
Ищет совпадения вводной строки и шаблона. - public boolean find()
Ищет подстроку вводной строки, которая совпадает с шаблоном. - public boolean find(int start)
Ищет подстроку вводной строки, которая совпадает с шаблоном начиная с указанного индекса. - public boolean matches()
Ищет совпадения всей строки и шаблона.
Методы замещения
Для замещения текста во вводной строке в языке Java предусмотрены следующие методы:
- public Matcher appendReplacement(StringBuffer sb, String replacement)
Метод реализует объединение и замену строки. - public StringBuffer appendTail(StringBuffer sb)
Метод реализует объединение и замену строки. - public String replaceAll(String replacement)
Заменяет все подстроки вводной строки, которая совпадает с шаблоном, указанным во вводной строке. - public String replaceFirst(String replacement)
Заменяет первую подстроку вводной строки, которая совпадает с шаблоном. - public static String quoteReplacement(String s)
Этот метод возвращает литеральную замену стоки для указанной строки.
Для понимания того, как все эти методы работают на практике, рассмотрим примеры простых приложений.
Метод find()
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexFindMethodDemo < public static void main(String[] args) < String regularExpression = "\\bjava\\b"; String inputString = "java java java2ee java"; Pattern pattern = Pattern.compile(regularExpression); Matcher match = pattern.matcher(inputString); int matchCounter = 0; System.out.println("Now we will use method find(). "); while (match.find())< matchCounter++; System.out.println("start(): " + match.start()); System.out.println("end(): " + match.end()); System.out.println("Number of match: " + matchCounter); >> >
В результате работы программы мы получим следующий результат:
/*Some system messages*/ Now we will use method find(). start(): 0 end(): 4 Number of match: 1 start(): 5 end(): 9 Number of match: 2 start(): 18 end(): 22 Number of match: 3
Метод lookingAt()
Пример:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexLookingAtMethodDemo < public static void main(String[] args) < String regularExpression = "Java"; String inputString = "Java Developer"; Pattern pattern; Matcher match; pattern = Pattern.compile(regularExpression); match = pattern.matcher(inputString); System.out.println("Input string: " + inputString); System.out.println("Regular expression: " + regularExpression); System.out.println("Using method lookingAt(): " + match.lookingAt()); System.out.println("Matches: " + match.matches()); >>
В результате работы программы мы получим следующий результат:
/*Some system messages*/ Input string: Java Developer Regular expression: Java Using method lookingAt(): true Matches: false
Метод replaceAll()
Пример:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class ReplaceFirstMethodDemo < public static void main(String[] args) < String regularExpression = "C#"; String inputString = "C# is the most popular programming language in the world. You should learn C#."; String realSituation = "Java"; Pattern pattern = Pattern.compile(regularExpression); Matcher match = pattern.matcher(inputString); System.out.println("Some people say:"); System.out.println(inputString); inputString = match.replaceAll(realSituation); System.out.println("But frankly speaking:"); System.out.println(inputString); >>
В результате работы программы мы получим следующий результат:
/*Some system messages*/ Some people say: C# is the most popular programming language in the world. You should learn C#. But frankly speaking: Java is the most popular programming language in the world. You should learn Java.
Метод appendReplacement()
Пример:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class AppendReplacementMethodDemo < public static void main(String[] args) < String regularExpression = "bla"; String inputString = "blablablaReallyblablablaImportantblablaInformationblabla"; String replace = " "; System.out.println("Initial input string:"); System.out.println(inputString); Pattern pattern = Pattern.compile(regularExpression); Matcher match = pattern.matcher(inputString); StringBuffer stringBuffer = new StringBuffer(); while (match.find())< match.appendReplacement(stringBuffer, replace); >match.appendTail(stringBuffer); System.out.println("Final input string:"); System.out.println(stringBuffer.toString()); > >
В результате работы программы мы получим следующий результат:
/*Some system messages*/ Initial input string: blablablaReallyblablablaImportantblablaInformationblabla Final input string: Really Important Information
В этом уроке мы изучили что такое регулярные выражения и основные методы, которые используются при работе с ними. Мы также рассмотрели примеры простых приложений с практическим применением регулярных выражений.
В следующем уроке мы более глубоко изучим, что такое методы и как они работают в языке программирования Java.
Полезности
Туториалы
Системный дизайн
Собеседования
Студенты
Задачи
Немного о себе
Приветствую! Меня зовут Евгений. На этом сайте я пишу о разработке программного обеспечения. Связаться со мной вы можете по email: proselytear@yahoo.com Имеет смысл, предварительно ознакомиться вот с этим FAQ разделом.
Недавние публикации
- Механизмы CAS и FAA глазами Java разработчика
- ExecutorService в Java и примеры его применения.
- Особенности работы PreparedStatement в JDBC
- Основы кэширования в Hibernate
- Феномены чтения глазами разработчика
Copyright © 2023 PROSELYTE.
Omega WordPress Theme by ThemeHall