Как извлечь повторяющуюся часть строки?

Я пытаюсь извлечь повторяющуюся часть строки с помощью регулярного выражения Java.

Моя строка: s01e04:11:08

Регулярное выражение: ^s(\\d+)e(\\d+)(:\\d+)*$

Регулярное выражение совпадает, но когда я пытаюсь извлечь третью группу, оно возвращает только последнюю ее часть.

Ожидается: :11:08

Получил: :08

Полный код:

public static void main( String args[] ) {
        String marker = "s01e04:11:08";
        Pattern r = Pattern.compile("^s(\\d+)e(\\d+)(:\\d+)*$");
        Matcher matcher = r.matcher(marker);

        if (matcher.find()) {
            System.out.println(matcher.group(3));
        }
    }
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
0
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Добавьте группу захвата вокруг повтора:

^s(\\d+)e(\\d+)((:\\d+)*)$
               ^        ^

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

^s(\\d+)e(\\d+)((?::\\d+)*)$
                 ^^

Спасибо за ответ. Как я понял, неважно, сколько включенных групп будет в одной из групп первого уровня. Или есть способ получить одну из вложенных подгрупп группы первого уровня? Что-то вроде индексации 2D-массива (group[1][2]), не обязательно в Java.

stand alone 29.05.2018 05:23

Я нашел ответ. Если мы используем ^s(\\d+)e(\\d+)(:\\d+)*$ для сопоставления с s01e04, мы получим null при получении 3 группы. Если для сопоставления с s01e04:11:08 мы получим :08 - последний повторяющийся кусок группы 3. Если мы будем использовать ^s(\\d+)e(\\d+)((:\\d+)*)$, мы получим "" в первом случае и :11:08 во втором случае. Кроме того, с помощью второго выражения мы можем ссылаться на последний повторяющийся фрагмент (внутреннюю группу) группы 3 с индексом 4. И если мы хотим отключить возможность ссылаться на группу 4, мы можем использовать выражение, не захватывающее повторяющуюся группу: ^s(\\d+)e(\\d+)((?::\\d+)*)$

stand alone 29.05.2018 17:52

Ваш шаблон не соответствует 1-му ":".

Попробуйте использовать это.

("^s(\\d+)e(\\d+)((:\\d+)+)$")

(:\\d+)+ соответствует: dd один или несколько раз.

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

Замените первый пробел между двумя цифрами косой чертой
Регулярное выражение PCRE для удаления пробела перед точкой и добавления одной после нее, но не влияет на многоточие
Дублируйте строку внутри файла и перезапишите другую с помощью sed
Регулярное выражение, чтобы найти большой кусок текста между разделителями
Необязательно сопоставление символа с использованием утверждения просмотра назад
Как использовать regExp, чтобы найти значение в ячейке и поместить в следующую строку в электронной таблице?
Webpack - как использовать загрузчик для файла, заканчивающегося заданной строкой?
Регулярное выражение: как создать шаблон для соответствия хотя бы одному символу нижнего регистра, символу верхнего регистра, цифре и хотя бы одному символу между [$ @ # &!]
НЕКОТОРЫЕ символы табуляции не совпадают в сценариях оболочки, но совпадают в командной строке
Поиск подстрок, заключенных в специальные символы в Swift