Matcher find java как работает
Перейти к содержимому

Matcher find java как работает

  • автор:

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. Часть II: Pattern, Matcher

Что Вы знаете о обработке строк в Java? Как много этих знаний и насколько они углублены и актуальны? Давайте попробуем вместе со мной разобрать все вопросы, связанные с этой важной, фундаментальной и часто используемой частью языка. Наш маленький гайд будет разбит на две публикации:

  1. String, StringBuffer, StringBuilder (реализация строк)
  2. Pattern, Matcher (регулярные выражения)

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

Регулярные выражения (regular expressions, далее РВ) — мощное и эффективное средство для обработки текста. Они впервые были использованы в текстовых редакторах операционной системы UNIX (ed и QED) и сделали прорыв в электронной обработке текстов конца XX века. В 1987 году более сложные РВ возникли в первой версии языка Perl и были основаны на пакете Henry Spencer (1986), написанном на языке С. А в 1997 году, Philip Hazel разработал Perl Compatible Regular Expressions (PCRE) — библиотеку, что точно наследует функциональность РВ в Perl. Сейчас PCRE используется многими современными инструментами, например Apache HTTP Server.

Большинство современных языков программирования поддерживают РВ, Java не является исключением.

Механизм

Существует две базовые технологии, на основе которых строятся механизмы РВ:

  • Недетерминированный конечный автомат (НКА) — «механизм, управляемый регулярным выражением»
  • Детерминированный конечный автомат (ДКА) — «механизм, управляемый текстом»

ДКА — механизм, который анализирует строку и следит за всеми «возможными совпадениями». Его работа зависит от каждого просканированного символа текста (то есть ДКА «управляется текстом»). Даний механизм сканирует символ текста, обновляет «потенциальное совпадение» и резервирует его. Если следующий символ аннулирует «потенциальное совпадение», то ДКА возвращается к резерву. Нет резерва — нет совпадений.

Логично, что ДКА должен работать быстрее чем НКА (ДКА проверяет каждый символ текста не более одного раза, НКА — сколько угодно раз пока не закончит разбор РВ). Но НКА предоставляет возможность определять ход дальнейших событий. Мы можем в значительной степени управлять процессом за счет правильного написания РВ.

Регулярные выражения в Java используют механизм НКА.

Эти виды конечных автоматов более детально рассмотрены в статье «Регулярные выражения изнутри».

Подход к обработке

В языках программирования существует три подхода к обработке РВ:

  • интегрированный
  • процедурный
  • объектно-ориентированный

Для обработки регулярных выражений в Java используют объектно-ориентированный подход.

Реализация

Для работы с регулярными выражениями в Java представлен пакет java.util.regex. Пакет был добавлен в версии 1.4 и уже тогда содержал мощный и современный прикладной интерфейс для работы с регулярными выражениями. Обеспечивает хорошую гибкость из-за использования объектов, реализующих интерефейс CharSequence.
Все функциональные возможности представлены двумя классами, интерфейсом и исключением:

Pattern

Класс Pattern представляет собой скомпилированное представление РВ. Класс не имеет публичных конструкторов, поэтому для создания объекта данного класса необходимо вызвать статический метод compile и передать в качестве первого аргумента строку с РВ:

// XML тэг в формате Pattern pattern = Pattern.compile("^<([a-z]+)([^>]+)*(?:>(.*)|\\s+\\/>)$"); 

Также в качестве второго параметра в метод compile можно передать флаг в виде статической константы класса Pattern, например:

// email адрес в формате xxx@xxx.xxx (регистр букв игнорируется) Pattern pattern = Pattern.compile("^([a-z0-9_\\.-]+)@([a-z0-9_\\.-]+)\\.([a-z\\.])$", Pattern.CASE_INSENSITIVE); 

Таблица всех доступных констант и эквивалентных им флагов:

Constant Equivalent Embedded Flag Expression
1 Pattern.CANON_EQ
2 Pattern.CASE_INSENSITIVE (?i)
3 Pattern.COMMENTS (?x)
4 Pattern.MULTILINE (?m)
5 Pattern.DOTALL (?s)
6 Pattern.LITERAL
7 Pattern.UNICODE_CASE (?u)
8 Pattern.UNIX_LINES (?d)

Иногда нам необходимо просто проверить есть ли в строке подстрока, что удовлетворяет заданному РВ. Для этого используют статический метод matches, например:

// это hex код цвета? if (Pattern.matches("^#?([a-f0-9]|[a-f0-9])$", "#8b2323")) < // вернет true // делаем что-то >

Также иногда возникает необходимость разбить строку на массив подстрок используя РВ. В этом нам поможет метод split:

Pattern pattern = Pattern.compile(":|;"); String[] animals = pattern.split("cat:dog;bird:cow"); Arrays.asList(animals).forEach(animal -> System.out.print(animal + " ")); // cat dog bird cow 
Matcher и MatchResult

Matcher — класс, который представляет строку, реализует механизм согласования (matching) с РВ и хранит результаты этого согласования (используя реализацию методов интерфейса MatchResult). Не имеет публичных конструкторов, поэтому для создания объекта этого класса нужно использовать метод matcher класса Pattern:

// будем искать URL String regexp = "^(https?:\\/\\/)?([\\da-z\\.-]+)\\.([a-z\\.])([\\/\\w \\.-]*)*\\/?$"; String url = "http://habrahabr.ru/post/260767/"; Pattern pattern = Pattern.compile(regexp); Matcher matcher = pattern.matcher(url); 

Но результатов у нас еще нет. Чтобы их получить нужно воспользоваться методом find. Можно использовать matches — этот метод вернет true только тогда, когда вся строка соответствует заданному РВ, в отличии от find, который пытается найти подстроку, которая удовлетворяет РВ. Для более детальной информации о результатах согласования можно использовать реализацию методов интерфейса MatchResult, например:

// IP адрес String regexp = "(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.)(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"; // для сравнения работы find() и matches() String goodIp = "192.168.0.3"; String badIp = "192.168.0.3g"; Pattern pattern = Pattern.compile(regexp); Matcher matcher = pattern.matcher(goodIp); // matches() - true, find() - true matcher = pattern.matcher(badIp); // matches() - false, find() - true // а теперь получим дополнительную информацию System.out.println(matcher.find() ? "I found '"+matcher.group()+"' starting at index "+matcher.start()+" and ending at index "+matcher.end()+"." : "I found nothing!"); // I found the text '192.168.0.3' starting at index 0 and ending at index 11. 

Также можно начинать поиск с нужной позиции используя find(int start). Стоит отметить что существует еще один способ поиска — метод lookingAt. Он начинает проверку совпадений РВ с начала строки, но не требует полного соответствия, в отличии от matches.
Класс предоставляет методы для замены текста в указанной строке:

appendReplacement(StringBuffer sb, String replacement) Реализует механизм «добавление-и-замена» (append-and-replace). Формирует обьект StringBuffer (получен как параметр) добавляя replacement в нужные места. Устанавливает позицию, которая соответствует end() последнего результата поиска. После этой позиции ничего не добавляет.
appendTail(StringBuffer sb) Используется после одного или нескольких вызовов appendReplacement и служит для добавления оставшейся части строки в объект класса StringBuffer, полученного как параметр.
replaceFirst(String replacement) Заменяет первую последовательность, которая соответствует РВ, на replacement. Использует вызовы методов appendReplacement и appendTail.
replaceAll(String replacement) Заменяет каждую последовательность, которая соответствует РВ, на replacement. Также использует методы appendReplacement и appendTail.
quoteReplacement(String s) Возвращает строку, в которой коса черта (‘ \ ‘) и знак доллара (‘ $ ‘) будут лишены особого смысла.
Pattern pattern = Pattern.compile("a*b"); Matcher matcher = pattern.matcher("aabtextaabtextabtextb the end"); StringBuffer buffer = new StringBuffer(); while (matcher.find()) < matcher.appendReplacement(buffer, "-"); // buffer = "-" ->"-text-" -> "-text-text-" -> "-text-text-text-" > matcher.appendTail(buffer); // buffer = "-text-text-text- the end" 
PatternSyntaxException

Неконтролируемое (unchecked) исключение, возникает при синтаксической ошибке в регулярном выражении. В таблице ниже приведены все методы и их описание.

getDescription() Возвращает описание ошибки.
getIndex() Возвращает индекс строки, где была найдена ошибка в РВ
getPattern() Возвращает ошибочное РВ.
getMessage() getDescription() + getIndex() + getPattern()

Java RegEx: использование регулярных выражений на практике

Аватарка пользователя Марина Александровна

Рассмотрим регулярные выражения в Java с учётом особенностей языка и с практическим применением для решения нескольких задач.

Рассмотрим регулярные выражения в Java, затронув синтаксис и наиболее популярные конструкции, а также продемонстрируем работу RegEx на примерах.

  1. Основы регулярных выражений
  2. Регулярные выражения в Java
  3. Примеры использования регулярных выражений в Java

Основы регулярных выражений

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

Определение

Регулярные выражения представляют собой формальный язык поиска и редактирования подстрок в тексте. Допустим, нужно проверить на валидность e-mail адрес. Это проверка на наличие имени адреса, символа @ , домена, точки после него и доменной зоны.

Вот самая простая регулярка для такой проверки:

^[A-Z0-9+_.-]+@[A-Z0-9.-]+$ 

В коде регулярные выражения обычно обозначается как regex, regexp или RE.

Синтаксис RegEx

Символы могут быть буквами, цифрами и метасимволами, которые задают шаблон:

Java RegEx: использование регулярных выражений на практике 1

Есть и другие конструкции, с помощью которых можно сокращать регулярки:

  • \d — соответствует любой одной цифре и заменяет собой выражение [0-9];
  • \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, что это элемент регулярки. Пример записи поиска символов пробела:

String regex = "\\s"; 

Ключевые классы

Java RegExp обеспечиваются пакетом java.util.regex. Здесь ключевыми являются три класса:

  1. Matcher — выполняет операцию сопоставления в результате интерпретации шаблона.
  2. Pattern — предоставляет скомпилированное представление регулярного выражения.
  3. 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 

Телефонный номер

Регулярное выражение для валидации номера телефона:

^((8|\+7)[\- ]?)?(\(?\d\)?[\- ]?)?[\d\- ]$ 

Эта регулярка ориентирована на российские мобильные номера, а также на городские с кодом из трёх цифр. Попробуйте написать код самостоятельно по принципу проверки e-mail адреса.

IP адрес

А вот класс для определения валидности IP адреса, записанного в десятичном виде:

private static boolean checkIP(String input) < return input.matches("((0|1\\d|2([0-4][0-9]|5[0-5]))\\.)(0|1\\d|2([0-4][0-9]|5[0-5]))"); > 

Правильное количество открытых и закрытых скобок в строке

На каждую открытую должна приходиться одна закрытая скобка:

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("(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|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]); > 
25/11/2020 30/11/2020 

А вот использование различных режимов квантификаторов, принцип работы которых мы рассмотрели чуть ранее.

Жадный режим

Pattern pattern = Pattern.compile("a+"); Matcher matcher = pattern .matcher("aaa"); while (matcher.find())
Найдено от 0 дo 2 

В заданном шаблоне первый символ – a . Matcher сопоставляет его с каждым символом текста, начиная с нулевой позиции и захватывая всю строку до конца, в чём и проявляется его «жадность». Вот и получается, что заданная стартовая позиция – это 0, а последняя – 2.

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

Pattern pattern = Pattern.compile("a++"); Matcher matcher = pattern .matcher("aaa"); while (matcher.find())
Найдено от 0 дo 2 

Принцип, как и в жадном режиме, только поиск заданного символа в обратном направлении не происходит. В приведённой строке всё аналогично: заданная стартовая позиция – это 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 и её классов.

Python RegEx: практическое применение регулярок

А какие примеры использования регулярных выражений в Java хотели бы видеть вы? Напишите в комментариях.

Matcher find java как работает

Кривой regex.. скопировал и попробовал на java17 — не ищет однострочный(//) комментарий, не учитывает перенос строк в многострочном комментарии (/*. */) Моя версия рабочая. Проверил на этом java-файле

(?s) — включает многострочный режим только для 3-ей группы И внутри третьей группы:

обязательно подчеркнутую часть нужно сделать ленивой, иначе загребать будет жадно от первого найденного /* по самый последний */. https://regex101.com/ — здесь можно посмотреть эффект жадности если убрать знак «?» из regex’а и вставить код из прикрепленного файла.

Евгения Уровень 47
19 февраля 2022

Помогите, пожалуйста, с последним примером. Я его скопировала, вставила в Идею. Далее сказано: Выполните приложение с файлом ExtCmnt.java в качестве входного: java ExtCmnt ExtCmnt.java out Если эту строчку вставить в параметры, ничего не работает. Я уже пыталась и полный путь к файлу прописать — ничего не получается. Подскажите, как можно это сделать.

Макс Дудин Уровень 41
18 мая 2021
Вот это прикольно. особенно последнее
Дмитрий Уровень 24
11 октября 2020

 Следующий пример демонстрирует использование методов groupCount() и group(int group): Pattern p = Pattern.compile("(.(.(.)))"); Matcher m = p.matcher("abc"); m.find(); System.out.println(m.groupCount()); for (int i = 0; i  

В вашем шаблоне 3 группs захвата, поэтому .groupCount() возвращает 3. Обратите внимание, что это не возвращает, сколько совпадений было найдено.

Ivan D Уровень 35
2 сентября 2020
Прям кайфую от чтения красивого кода с объяснениями.
Тимофей Уровень 26
15 июля 2020

Не работает, если реально есть в файле многострочный комментарий. Вот это регулярное выражение - ".*/\\*.*\\*/|.*//.*$"

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

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