2016-05-13 3 views
0
std::regex r("((.)(.))(.)"); 

Выполнение этого задания на трехбуквенной строке просто вернет 5 совпадений. Coliru.Как получить иерархию совпадений из регулярного выражения

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

Похоже, что boost имеет что-то подобное с "nested matches". Это верно? И могу ли я сделать это в C++ 11 без повышения?

Extra: чуть менее тривиальная игрушка пример, где это может быть полезно:

((,[0-9]+)+)((,[a-z])+) 

Это соответствует ряду чисел, следуя за серией слов, все через запятую. Я хотел бы отделить число-матчи от слова-матчей, вместо того, чтобы иметь плоскую серию матчей.

+0

Для чего? Как вы полагаете, что сможете сделать это с таким объектом, с которым вы не можете обойтись? –

+0

@IgorTandetnik, я только что добавил немного более сложный пример, чтобы мотивировать это. –

+3

Вы, кажется, полагаете, что получите отдельное соответствие для каждого повторения группы. Это не работает 'std :: regex'. Вы получите ровно столько совпадений, что в регулярном выражении есть открытые парсеры, плюс один. Другими словами, количество возвращаемых совпадений фиксируется синтаксисом выражения и не зависит от сопоставления ввода. –

ответ

0

Дело в регулярном выражении состоит в том, что они не являются рекурсивными анализаторами спуска. Но вы можете использовать комбинацию регулярных выражений и C++ (или любого другого языка, действительно).

Просто к сведению, есть некоторые проблемы с этим регулярным выражением:

((,[0-9]+)+)((,[a-z])+) 

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

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

((,[0-9]+)+)((,[a-zA-Z]+)+) 

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

Теперь, когда это исправлено, я могу объяснить, как вы могли бы выполнить то, что хотите.

Все числовые совпадения находятся в matches[1]. Все алфавитные совпадения находятся в matches[3].

Вы можете получить каждый отдельный элемент в числовом списке, разделив его на ,. То же самое касается алфавитного списка.

+0

В этом случае 'match [2]' будет совпадать с 'match [1]'? И 'match [4]' совпадает с 'match [5]'? –

+0

@AaronMcDaid Нет, 'matches [2]' будет удерживать только последнюю итерацию, которая соответствует. То же самое для 'matches [4]'. Но нет совпадений [5] '(подсчитайте количество открывающих скобок). – Laurel

+0

Извините, я имел в виду '3' вместо' 5'! Во всяком случае, теперь я понимаю, спасибо. Тот факт, что последний матч захвачен, потенциально очень полезен - это позволит автоматической схеме удалять отдельные совпадения повторно –

Смежные вопросы