Java регулярные повторяющиеся группы захвата - PullRequest
1 голос
/ 01 мая 2020

Учитывая следующую строку: "$ {test.one} $ {test.two}" Я бы хотел, чтобы мое регулярное выражение возвращало два совпадения, а именно "test.one" и "test.two". Для этого у меня есть следующий фрагмент:

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

public class RegexTester {

    private static final Pattern pattern = Pattern.compile("\\$\\{((?:(?:[A-z]+(?:\\.[A-z0-9()\\[\\]\"]+)*)+|(?:\"[\\w/?.&=_\\-]*\")+)+)}+$");

    public static void main(String[] args) {
        String testString = "${test.one}${test.two}";

        Matcher matcher = pattern.matcher(testString);

        while (matcher.find()) {
            for (int i = 0; i <= matcher.groupCount(); i++) {
                System.out.println(matcher.group(i));
            }
        }
    }
}

У меня тоже есть кое-что еще, потому что я хочу, чтобы это также было действительное совпадение $ {test.one} $ {"привет "}.

Итак, я просто хочу, чтобы оно совпадало с чем-либо внутри $ {}, если оно соответствует формату: something.somethingelse (только там alphanumeri c) или something.somethingElse() или "something inside of quotations" (alphanumeri c плюс некоторые другие символы). У меня работает основное регулярное выражение, или я так думаю, но когда я запускаю код, он находит две группы:

$ {test.two} test.two

Я хочу, чтобы вывод быть

test.one test.two

Ответы [ 2 ]

2 голосов
/ 01 мая 2020

По сути, основная проблема вашего регулярного выражения в том, что он совпадает только в конце строки, и вы сопоставляете гораздо больше символов, чем просто буквы с [A-z]. Ваша группировка тоже кажется выключенной.

Если вы загрузите свое регулярное выражение в regex101, вы увидите , оно соответствует

  • \$\{
  • ( - начало группа захвата
    • (?: - начало группы без захвата
      • (?:[A-z]+ - начало группы без захвата, и она соответствует 1+ символам между A и z ( ваша первая ошибка )
        • (?:\.[A-z0-9()\[\]\"]+)* - 0 или более повторений букв ., а затем 1+ букв, цифр, (, ), [ , ], ", \, ^, _ и обратный тик
      • )+ - повторить группу без захвата 1 или более раз
      • | - или
      • (?:\"[\w/?.&=_\-]*\")+ - 1 или более вхождений ", 0 или более слов, /, ?, ., & , =, _, - символов, а затем "
      • )+ - повторите групповой шаблон 1+ раз
    • ) - конец группы без захвата
  • }+ - 1+ } символов
  • $ - конец строки.

Для соответствия При вхождении вашего шаблона в строку вам необходимо использовать

\$\{(\"[^\"]*\"|\w+(?:\(\))?(?:\.\w+(?:\(\))?)*)}

См. демонстрационный пример regex , получить значение группы 1 после того, как совпадение найдено. Подробности:

  • \$\{ - подстрока ${
  • (\"[^\"]*\"|\w+(?:\(\))?(?:\.\w+(?:\(\))?)*) - Группа захвата 1:
    • \"[^\"]*\" - ", 0+ символы, отличные от ", а затем "
    • | - или
    • \w+(?:\(\))? - 1+ символов слова и необязательная () подстрока
    • (?:\.\w+(?:\(\))?)* - 0 или более повторений ., а затем 1+ символов слова и необязательной () подстроки
  • } - } char.

См. Java демо :

String s = "${test.one}${test.two}\n${test.one}${test.two()}\n${test.one}${\"hello\"}";
Pattern pattern = Pattern.compile("\\$\\{(\"[^\"]*\"|\\w+(?:\\(\\))?(?:\\.\\w+(?:\\(\\))?)*)}");
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
    System.out.println(matcher.group(1)); 
} 

Выход:

test.one
test.two
test.one
test.two()
test.one
"hello"
0 голосов
/ 02 мая 2020

Вы можете использовать регулярное выражение

(?<=\$\{")[a-z]+(?="\})|(?<=\$\{)[a-z]+\.[a-z]+(?:\(\))?(?=\})

, в котором нет групп захвата. Классы символов [a-z] могут быть изменены по мере необходимости, если они не содержат двойные кавычки, точку или правую скобку.

Демо

Java Движок regex выполняет следующие операции.

(?<=\$\{")  # match '${"' in a positive lookbehind
[a-z]+      # match 1+ lowercase letters 
(?="\})     # match '"}' in a positive lookahead
|           # or 
(?<=\$\{)   # match '${' in a positive lookbehind
[a-z]+      # match 1+ lowercase letters 
\.[a-z]+    # match '.' followed by 1+ lowercase letters
(?:\(\))?   # optionally match `()`
(?=\})      # match '}' in a positive lookahead
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...