Как захватить повторяющиеся шаблоны с помощью регулярных выражений в C ++

0

Моя проблема связана с токенизацией регулярных выражений в C++.

У меня есть следующий шаблон регулярного выражения:

**const regex PRx ("^ TxD = <(@&[^(@&)]{1,32}@&){2,}>;");**

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

 TxD = <@&Mag@&@&Hael@&@&Io12n@&>;

 TxD = <@&Atx@&@&Depoc@&@&Lsadiz@&@&gfhg@&@&kdkdj@&>;

Обратите внимание, что пространство существует в начале каждой строки (как показано в regex PRx после привязки ^).

Следующий код отвечает за парсинг над шаблонами соответственно

vector<DFG> IP; // DFG is a class type

vector<int> MIS;
MIS.push_back(1);

const sregex_token_iterator Endx;

for (sregex_token_iterator IPF(DOC.begin(), DOC.end(), PRx, MIS); IPF != Endx;)
{
    string SIN = (*IPF).str().c_str(); 
    IPF++;      
    IP.push_back(DFG(SIN));  /* The constructor of DFG is responsible for pushing SIN to a 
                                 vector data member object of string type */ 
}

Как показано в шаблоне PRx регулярного выражения, он пытается захватить все шаблоны, заключенные между разделителем "@&"; однако проблема заключается в том, что он захватывает только последний сопоставленный шаблон. Например, в первой строке он будет сообщать только "@& Io12n @&", а во второй строке он сообщает только "@& kdkdj @&".

Ожидаемый вывод из первой строки (для иллюстрации):

@&Mag@&
@&Hael@&
@&Io12n@&

А из второй строки (для иллюстрации):

@&Atx@&
@&Depoc@&
@&Lsadiz@&
@&gfhg@&
@&kdkdj@&

(Обратите внимание, что вывод, показанный выше, не должен отображаться, а скорее такой, чтобы каждый найденный шаблон сохранялся отдельно в векторном объекте SIN)

Это будет работать, только если я удалил шаблоны "^ TxD = <" и ">;" и проверку диапазона "{2,}" из PRx, и я не хочу этого делать. Я не уверен, почему он не смог захватить все шаблоны! Не могли бы вы представить свои мысли и оценку по этому вопросу.

Спасибо!

  • 1
    В вашем паттерне у вас есть пробел после начального якоря ^ , это было преднамеренно ?, а также второй пример: Lsadiz и gfhg пропустили свой конец @& ? отредактируйте ваш вопрос и покажите ожидаемый результат для каждого примера.
  • 0
    Пространство после якоря является намеренным. Я исправил второй пример строки. Спасибо!
Теги:
tokenize

1 ответ

0
Лучший ответ

Если ваш regex engine поддерживает \G вы можете использовать этот шаблон

(?:^\sTxD\s=\s<(?=(?1){2,}>;$)|\G)(@&[^@&]{1,32}@&)(?=(?1)|>;$)

демонстрация


Основываясь на вашем комментарии ниже, я думаю, вам нужно использовать два разных шаблона регулярных выражений, первый для фильтрации ваших данных на основе критериев ^ TxD, {2,}, {1,32} и >; во-первых, так

^\sTxD\s=\s(?=<((@&[^@&]{1,32}@&){2,})>;$)

демонстрация
и выполнить еще один простой шаблон в матче # 1

  • 0
    Спасибо, что нашли способ заставить его работать. К сожалению, библиотека C ++ Regex поддерживает синтаксисы ECMAScript, POSIX basic и extended, awk, grep и egrep, и эта опция не поддерживается.
  • 0
    Вы не можете привязать свой шаблон с помощью ^ TxD и >; в конце и ожидаем захватить переменное количество паттерна с помощью одного регулярного выражения.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню