RegEx для сопоставления подвыражения - PullRequest
0 голосов
/ 10 мая 2019

Когда я использую регулярное выражение типа

std::regex midiNoteNameRegex("([cdefgab])([b#]{0,1})([0-9]))|([0-9]{3})|([A-Z0-9]{2})");

есть три подвыражения верхнего уровня, соединенных "|" в шаблоне которого будет соответствовать. Есть ли способ сказать, какой? Кроме тестирования их последовательно один за другим?

Если бы я использовал именованные подвыражения, это было бы легко, но в C ++ нет именованных подвыражений.

Как мне решить эту проблему?

Ответы [ 2 ]

2 голосов
/ 10 мая 2019

Учитывая группы в вашем регулярном выражении, это просто плоский поиск объекта совпадения,
который в C ++ является проверкой флага (int), без заметных накладных расходов.

    ( [cdefgab] )                 # (1)
    ( [b#]{0,1} )                 # (2)
    ( [0-9] )                     # (3)
 |  ( [0-9]{3} )                  # (4)
 |  ( [A-Z0-9]{2} )               # (5)

И возможное использование

wregex MyRx = wregex( "([cdefgab])([b#]{0,1})([0-9])|([0-9]{3})|([A-Z0-9]{2})", 0);

wstring::const_iterator start = str.begin();
wstring::const_iterator end   = str.end();
wsmatch m;

while ( regex_search( start, end, m, MyRx ) )
{
    if ( m[1].matched )       
        // First alternation
    else
    if ( m[4].matched )       
        // Second alternation
    else
    if ( m[5].matched )       
        // Third alternation
    start = m[0].second;
}
0 голосов
/ 10 мая 2019

У меня нет определенного ответа, но я думаю, что ответ, скорее всего, нет.

Именованная группа захвата не является обязательной функцией: http://www.cplusplus.com/reference/regex/ECMAScript/

Реализация именованной группы захвата, вероятно, не тривиальна и, вероятно, снижает производительность механизма регулярных выражений.

Нашел другой пост по этому вопросу, который согласен со мной: C ++ regex: Какая группа соответствует?

...