C ++ 11: Безопасная практика с регулярным выражением двух возможных количеств совпадений

С это регулярное выражение, Я хотел бы сопоставить время с или без миллисекунд (мс) поле. Для полноты я напишу здесь регулярное выражение (я удалил якоря в регулярном выражении для включения многострочного):

^(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(?:|(?:\.)([0-9]{1,6}))$

Я вроде не понимаю поведение C ++ в этом. Теперь вы видите в regex101, количество групп захвата зависит от строки. Если нет ms, это 3 + 1 (так как C ++ использует match [0] для сопоставленного шаблона), а если есть ms, то это 4 + 1. Но тогда в этом примере:

std::regex timeRegex = std::regex(R"(^(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(?:|(?:\.)([0-9]{1,6}))$)");
std::smatch m;
std::string strT = std::string("12:00:09");
bool timeMatch = std::regex_match(strT, m, timeRegex);
std::cout<<m.size()<<std::endl;
if(timeMatch)
{
std::cout<<m[0]<<std::endl;
std::cout<<m[1]<<std::endl;
std::cout<<m[2]<<std::endl;
std::cout<<m[3]<<std::endl;
std::cout<<m[4]<<std::endl;
}

Мы видим, что m.size() всегда 5, есть ли поле мс или нет! m[4] пустая строка, если нет поля ms. Это поведение по умолчанию в регулярном выражении C ++? Или я должен попробовать / поймать (или другие меры безопасности), если сомневаетесь в размере? Я имею в виду … даже размер здесь немного вводит в заблуждение!

0

Решение

m.size() всегда будет количество отмеченных подвыражений в вашем выражении плюс 1 (для всего выражения).

В вашем коде у вас есть 4 помеченных подвыражения, независимо от того, совпадают они или нет, не влияет на размер m,

Если вы хотите сейчас, если есть миллисекунды, вы можете проверить:

m[4].matched
3

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

m.size();// Returns the number of match results.
// a string is allocated for each 'Capture Group'
// and filled with the match substring.

Так как smatch является match_results

(увидеть)
http://www.cplusplus.com/reference/regex/match_results/

size возвращает количество совпадений ALLOCATED, которое зависит от количества групп захвата, содержащихся в вашем регулярном выражении.

Группы захвата:

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

http://www.regular-expressions.info/refcapture.html

Вот почему ваш размер будет выделен как 5, независимо от того, что вы в конечном итоге заполните regex_match (). Как и у других, есть Notex, пятый — полный матч.

Увидеть:
Что возвращает std :: match_results :: size?

2

std::smatch (А.к.а. std::match_results<std::string::const_iterator>) это в основном контейнер, который содержит элементы типа std::sub_match, Первый элемент — это результаты сопоставления для вашего полного выражения регулярного выражения, а последующие содержат совпадения для каждого подвыражения. Поскольку у вас есть 4 подвыражения, если вы используете шаблон, вы получите 5 результатов (4 + полное соответствие).

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