С это регулярное выражение, Я хотел бы сопоставить время с или без миллисекунд (мс) поле. Для полноты я напишу здесь регулярное выражение (я удалил якоря в регулярном выражении для включения многострочного):
^(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 ++? Или я должен попробовать / поймать (или другие меры безопасности), если сомневаетесь в размере? Я имею в виду … даже размер здесь немного вводит в заблуждение!
m.size()
всегда будет количество отмеченных подвыражений в вашем выражении плюс 1 (для всего выражения).
В вашем коде у вас есть 4 помеченных подвыражения, независимо от того, совпадают они или нет, не влияет на размер m
,
Если вы хотите сейчас, если есть миллисекунды, вы можете проверить:
m[4].matched
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, которое зависит от количества групп захвата, содержащихся в вашем регулярном выражении.
Группы захвата:
Скобки группируют регулярное выражение между ними. Они фиксируют текст, соответствующий регулярному выражению внутри них, в пронумерованную группу, которую можно повторно использовать с пронумерованной обратной ссылкой. Они позволяют применять операторы регулярных выражений ко всему сгруппированному регулярному выражению.
Вот почему ваш размер будет выделен как 5, независимо от того, что вы в конечном итоге заполните regex_match (). Как и у других, есть Notex, пятый — полный матч.
std::smatch
(А.к.а. std::match_results<std::string::const_iterator>
) это в основном контейнер, который содержит элементы типа std::sub_match
, Первый элемент — это результаты сопоставления для вашего полного выражения регулярного выражения, а последующие содержат совпадения для каждого подвыражения. Поскольку у вас есть 4 подвыражения, если вы используете шаблон, вы получите 5 результатов (4 + полное соответствие).