Использование флага regex g в java

Можно ли использовать глобальный флаг g регулярного выражения в шаблоне Java?

Пробовал с final Pattern pattern = Pattern.compile(regex,Pattern.DOTALL); но он не ведет себя как глобальный флаг.

Есть ли у нас какое-нибудь обходное решение в java?

Мое регулярное выражение:
private final String regex = "(public|private|protected|static|final|abstract|synchronized|volatile)\\s*([\\w<>\\[\\]]+)\\s*(\\w+)\\s*\\(([\\w\\s\\w,<>\\[\\]]*)?\\)\\s*(\\bthrows\\b)?[\\s\\w\\s,\\w]*\\{[\\n\\t]*(.+)[\\n\\t]*((return|throw){1}\\s*)(\\w*)\\s*;\\s*[\\}]";

input - это содержимое файла, что-то вроде упомянутого в ссылке на регулярное выражение ниже: https://regex101.com/r/u7vanR/3

Я хочу, чтобы шаблон java находил оба вхождения, но с флагами java regex он просто находит первый, а не оба.

Похоже, что вариант регулярного выражения на этой странице по умолчанию считает .* неохотным. В Java вам нужно явно указать его в .*?, чтобы он соответствовал минимальному количеству текста. Также вам не нужно окружать экранированный \\}[...] (он уже экранирован с помощью \\).

Pshemo 04.08.2018 22:07

И я не уверен, для чего там {1}. Если квантификатор не указан, то по умолчанию регулярное выражение ищет единственное совпадение, поэтому обычно нам не нужно писать {1}. Это может быть полезно, если в регулярном выражении есть другие квантификаторы, такие как {2}{3}, чтобы показать, какая часть должна существовать один раз, дважды, трижды и так далее.

Pshemo 04.08.2018 22:11

здесь вопрос не о конкретном регулярном выражении, вы можете выбрать любое другое регулярное выражение, которое соответствует блоку предложения / кода / синтаксиса (несколько строк) в данном файле, я не могу получить все вхождения с использованием флага java regex. Для простого слова или однострочного соответствия он работает с использованием многострочного варианта, но не работает для блока предложения.

Sandeep Chauhan 05.08.2018 18:29

Я бы не сказал, что речь идет не о конкретном регулярном выражении, поскольку в Java по умолчанию установлен флаг Глобальный (более того, вы даже не можете его отключить). Но если вы не можете правильно сопоставить что-то, то проблема, скорее всего, кроется в шаблоне. В вашем случае возможной причиной может быть .*, который по умолчанию является жадным, поэтому он пытается сопоставить как можно больше текста, что на основе данных из вашей ссылки выглядит как сопоставление всех методов как один матч (например, start of first method{ .* end of last method}). Возможное решение для этого может заключаться в том, чтобы заставить .* не реагировать с .*?.

Pshemo 05.08.2018 19:20

Если вы все еще сталкиваетесь с некоторыми проблемами, то для оказания надлежащей помощи нам потребуется увидеть минимальный воспроизводимый пример и описание того, чего вы действительно хотите достичь.

Pshemo 05.08.2018 19:21

@Pshemo спасибо, я тоже попробую. Я не использовал. * но. +, так что мне нужно изменить его на. +? , также {1} и \\} с [...] не требуются, как вы правильно указали. но приведенное выше регулярное выражение такое же, как упомянуто в ссылке (без синтаксиса java) выше, и правильно соответствует обоим разделам, но при использовании в java не ведет себя одинаково.

Sandeep Chauhan 05.08.2018 19:44
.+ также по умолчанию является жадным, поэтому вам может потребоваться изменить его на версию .+?, неохотно. Но трудно сказать, понадобится ли это единственное изменение. В любом случае использование регулярного выражения для поиска методов в коде выглядит неправильно. Это больше похоже на работу парсера. В зависимости от вашей цели вы можете использовать такие инструменты, как antlr.org (например, для Java: stackoverflow.com/q/1931307).
Pshemo 05.08.2018 20:06
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
5
7
11 048
2

Ответы 2

У Java нет глобального флага. Вы можете получить все совпадения через find и group.

Pattern pattern = Pattern.compile("1");
Matcher matcher = pattern.matcher("111");
while (matcher.find()) {
    System.out.println(matcher.group());
}

На выходе

1
1
1

он не найдет оба совпадения, например, с флагом g в этом регулярном выражении, которое я использую: regex101.com/r/u7vanR/3

Sandeep Chauhan 04.08.2018 19:19

Измените свой вопрос, включив в него шаблон регулярного выражения и фактический результат / ожидаемый результат.

zhh 04.08.2018 19:25

добавил мое фактическое регулярное выражение, и ввод - это содержимое файла, как я упоминал в приведенной выше ссылке

Sandeep Chauhan 04.08.2018 19:36

Флаг «g» в Java не нужен. Есть методы с таким же эффектом, например:

replaceAll(regex, replacement)

Другие вопросы по теме