Как получить каждую итерацию группы в регулярном выражении как отдельной группы?

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

  • текст, начинающийся с данного префикса (скажем, это ab4)
  • Текст имеет тело из 4 блоков по 4 символа (вот что 4 в ab4 обозначает) каждый из которых может быть ASCII буквенно-цифровым, пробелом, скобками, дефисом или точкой (в основном a-zA-Z0-9 ()-.). Пример: abcd, .b a, , b(a.) все действительные отдельные блоки.
  • тело текста может быть пустым (ab4 является единственным контентом) или содержать до четырех блоков (ab4xxxx, ab4xxxxxxxx, ab4xxxxxxxxxxxx, ab4xxxxxxxxxxxxxxxx с x быть действующим персонажем)
  • конец текста с CR (возврат каретки — \r\n). Окончание считается завершающим символом и НЕ является частью тела.

До сих пор я придумал

.*ab4([a-zA-Z0-9 ()-.]{4}){1,4}\\r\\n.*

я использую регулярные выражения 101 чтобы проверить мое регулярное выражение, прежде чем добавить его в мой код C ++. Однако, если я введу

ab4aaa bbb ccc ddd \r\n

Я получаю следующую статистику:

  • Полное совпадение:

    0-25 'ab4aaa bbb ccc ddd \r\n'

  • Группа 1.:

    15-19 'ddd '

Верификатор регулярных выражений говорит мне, что

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

но, честно говоря, я понятия не имею, что это значит. Я старался (([a-zA-Z0-9 ()-.]{4}){1,4}) который не сильно изменился.

Я ищу лучшую группировку, а именно ту, которая расставляет 4 блока как отдельные группы. Для примера выше я ожидаю

  • Полное совпадение:

    0-25 'ab4aaa bbb ccc ddd \r\n'

    • Группа 1.:

    0-3 'aaa '

    • Группа 1.:

    4-7 'bbb '

    • Группа 3 .:

    8-11 'ccc '

    • Группа 4 .:

    12-15 'ddd '

2

Решение

Вы используете PCRE Regex Engine (с QRegularExpression), который не поддерживает стек захвата для каждой группы, поэтому вам придется использовать двухэтапный подход:

  • Извлеките целые совпадения, захватив часть, которая вам понадобится для дальнейшей обработки, и
  • Разделите каждый захват на части из 4 символов.

Первое извлекающее регулярное выражение будет

ab4((?:[a-zA-Z0-9 ().-]{4}){1,4})\\r\\n
^                 ^          ^

Обратите внимание, что я добавил в скобки круглые скобки вокруг интересующей вас части, а дефис находится в конце класса символов.

Используйте шаблон для извлечь все совпадения из текста.

Затем разделить match.captured(1) в подстроки длины 4. Вам на самом деле не нужно использовать регулярное выражение для этого шага, поскольку строка уже предварительно проверена во время первого шага регулярного выражения.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]