Разница между std:: regex_match и std:: regex_search?
Ниже была записана программа для получения информации "День" с использованием С++ 11 std:: regex_match и std:: regex_search. Однако использование первого метода возвращает false
, а второй метод возвращает true
(ожидается). Я прочитал документацию и уже существующий вопрос SO, связанный с этим, но я не понимаю разницу между этими двумя методами и когда мы должны использовать любой из них? Могут ли они использоваться как взаимозаменяемые для любой общей проблемы?
Разница между regex_match и regex_search?
#include<iostream>
#include<string>
#include<regex>
int main()
{
std::string input{ "Mon Nov 25 20:54:36 2013" };
//Day:: Exactly Two Number surrounded by spaces in both side
std::regex r{R"(\s\d{2}\s)"};
//std::regex r{"\\s\\d{2}\\s"};
std::smatch match;
if (std::regex_match(input,match,r)) {
std::cout << "Found" << "\n";
} else {
std::cout << "Did Not Found" << "\n";
}
if (std::regex_search(input, match,r)) {
std::cout << "Found" << "\n";
if (match.ready()){
std::string out = match[0];
std::cout << out << "\n";
}
}
else {
std::cout << "Did Not Found" << "\n";
}
}
Выход
Did Not Found
Found
25
Почему первый метод regex возвращает false
в этом случае?. regex
кажется правильным, поэтому в идеале оба должны были быть возвращены true
. Я запустил вышеуказанную программу, изменив std::regex_match(input,match,r)
на std::regex_match(input,r)
и обнаружив, что он все еще возвращает false.
Может ли кто-нибудь объяснить приведенный выше пример и, в общем, использовать случаи этих методов?
Ответы
Ответ 1
regex_match
возвращает только true
, когда вся входная последовательность согласована, а regex_search
будет успешной, даже если только подпоследовательность соответствует regex
.
Цитата из N3337,
§28.11.2/2 regex_match
[re.alg.match]
Эффекты: Определяет, существует ли соответствие между регулярным выражением e
и всей последовательности символов [first,last)
. ...
Возвращает true
, если такое совпадение существует, false
в противном случае.
Вышеприведенное описание относится к перегрузке regex_match
, которая берет пару итераторов в последовательность, подлежащую согласованию. Оставшиеся перегрузки определены в терминах этой перегрузки.
Соответствующая перегрузка regex_search
описывается как
§28.11.3/2 regex_search
[re.alg.search]
Эффекты: Определяет, существует ли какая-либо подпоследовательность внутри [first,last)
, которая соответствует регулярному выражению e
. ...
Возвращает true
, если такая последовательность существует, false
в противном случае.
В вашем примере, если вы измените regex
на r{R"(.*?\s\d{2}\s.*)"};
, оба regex_match
и regex_search
будут успешными (но результат совпадения - это не только день, но и вся строка даты).
Живая демонстрация измененной версии вашего примера, где день записывается и отображается как regex_match
, так и regex_search
.
Ответ 2
Это очень просто. regex_search
просматривает строку, чтобы найти, соответствует ли какая-либо часть строки регулярному выражению. regex_match
проверяет, соответствует ли целая строка регулярному выражению. В качестве простого примера можно привести следующую строку:
"one two three four"
Если я использую regex_search
в этой строке с выражением "three"
, это будет успешным, потому что "three"
можно найти в "one two three four"
Однако, если я использую regex_match
вместо этого, он потерпит неудачу, потому что "three"
- это не вся строка, а только ее часть.