Я хочу использовать функцию члена regex_search в c++ 11.
Однако я не могу найти правильные ответы для данного регулярного выражения.
Пример следующий:
Целевая строка: "abcd cd abefcd ababcddecd"
При регулярном выражении: "ab. * Cd" - это регулярное выражение основано на расширенном грамматике POSIX.
Ожидаемый результат: abcd, abcd cd, abcd cd abefcd, abcd cd abefcd ababcd, abcd cd abefcd ababcddecd, abefcd, abefcd ababcd, abefcd ababcddecd, ababcd, ababcddecd
библиотека для меня не знакома.
Итак, я не знаю, что делать, чтобы получить ожидаемый результат в приведенном выше примере.
Исходный код:
#include <regex>
#include <iostream>
using namespace std;
int main(void){
regex re("ab.*cd", regex::extended);
smatch m;
string s = "abcd cd abefcd ababcddecd";
// TO DO??
/*
while(regex_search(s, m, re)){
for(auto x:m) cout << x << " ";
cout << endl;
s = m.suffix().str();
}
*/
return 0;
}
Я предполагаю, что эта проблема вызывает библиотеку в С++ 11.
Я реализую короткий код для примера, описанного в исходном вопросе выше, с библиотекой.
Однако я не могу получить правильный ответ. regex_search возвращает только 0 всякий раз.
Так. Я использую в библиотеке Boost для реализации примера.
#include <string>
#include <map>
#include <boost/regex.hpp>
#include <iostream>
using namespace std;
int main(void){
boost::regex e("ab.*cd", boost::regex::extended);
std::string s("abcd cd abefcd ababcddecd");
boost::smatch m;
std::map<std::string, int> mm;
// I use a map for prevent redundant duplication of matched string
for(int i = 0; i < s.size(); i++){
for(int j = 1; j <= (s.size() - i); j++){
std::string ss = s.substr(i, j);
boost::smatch m;
if(boost::regex_search(ss, m, e)){
int temp = mm[m[0]];
if(temp == 0){
mm[m[0]] = 1;
cout << "Match string: " << m[0] << endl;
}
}
}
}
}
Makefile выглядит следующим образом:
CC = g++
FLAG = -g
FLAG_I = -I/usr/include
FLAG_L = -L/usr/lib -lboost_regex
OBJECTS = main.o
TARGET = main
$(Target) : $(OBJECTS)
$(CC) -o $(TARGET) $(OBJECTS) $(FLAG_L)
main.o : main.cpp
$(CC) $(FLAG) -c main.cpp $(FLAG_I)
Я получаю правильный ответ, используя этот код в Linux-машине, такой как fedora 19 с библиотекой Boost.
[user@localhost test]#make
g++ -g -c main.cpp -I/usr/include
g++ -o main main.o -L/usr/lib -lboost_regex
[user@localhost test]#./main
Match string: abcd
Match string: abcd cd
Match string: abcd cd abefcd
Match string: abcd cd abefcd ababcd
Match string: abcd cd abefcd ababcddecd
Match string: abefcd
Match string: abefcd ababcd
Match string: abefcd ababcddecd
Match string: ababcd
Match string: ababcddecd
Match string: abcddecd
[user@localhost test]#
-конец-
Операция *
в регулярных выражениях жадна: она ест все, что может, не нарушая остальную часть матча. Поэтому при поиске "abxxxabyyyab"
с ab.*ab
регулярное выражение соответствует всей строке; .*
соответствует "xxxabyyy"
. То, что вы ищете, - это не жадный поиск, где *
потребляет самую короткую подстроку, которая не нарушает совпадение. Для этого используйте *?
, При поиске "abxxxabyyyab"
с ab.*?ab
регулярное выражение соответствует "abxxxab"
и .*?
соответствует "xxx"
.
#include <regex>
#include <iostream>
using namespace std;
int main(void){
regex e("(a.*cd)", regex::extended);
string s = R"(abcd cd abefcd ababcddecd)";
string match = "";
size_t i = 0;
while (s.size() > i)
{
smatch m;
string ss = s.substr(0, i);
regex_search(ss, m, e);
if (m.size() > 1 && m[1] != match) {
cout << m[1] << endl;
match = m[1];
}
i++;
}
cin.get();
return 0;
}