这不是this或this问题的重复,因为我使用的是最新的g ++ 6.1。
以下是我正在尝试的一个简单示例:
int main() {
std::string data = "a,b,c,d,e,f,g";
std::smatch m;
regex_search(data, m, std::regex("(\\w)"));
std::cout << m.size() << std::endl;
for (auto i = 0U; i != m.size(); i++)
std::cout << m.position(i) << " " << m[i].str() << std::endl;
return 0;
}
此示例输出2作为匹配数,而我预期为7,因为data
中的每个字母都应与\w
匹配。我该如何解决这个问题?
此外,两个匹配都指向字符串开头的a
。
答案 0 :(得分:1)
regex_seach
不提供扫描整个字符串的任何工具,它只是在第一次匹配时停止。幸运的是<regex>
图书馆提供了std::regex_iterator
来完成工作:
int main() {
std::string data = "a,b,c,d,e,f,g";
std::regex exp = std::regex("(\\w)");
auto mbegin = std::sregex_iterator(data.begin(), data.end(), exp);
auto mend = std::sregex_iterator();
for (auto it = mbegin; it != mend; ++it)
cout << it->str() << endl;
return 0;
}
唯一需要注意的是,所使用的std::regex
的生命周期必须匹配(至少)迭代器中的一个,因为std::regex_iterator
在内部存储了一个指向它的指针。
答案 1 :(得分:1)
这是excerpt from Finding All Regex Matches at regular-expressions.info:
通过使用三个参数调用构造函数构造一个对象:字符串迭代器指示搜索的起始位置,字符串迭代器指示搜索的结束位置,和正则表达式对象。如果找到任何匹配项,则对象将在构造时保持第一个匹配项。使用默认构造函数构造另一个迭代器对象以获取序列结束迭代器。您可以将第一个对象与第二个对象进行比较,以确定是否还有其他匹配项。只要第一个对象不等于第二个对象,就可以取消引用第一个对象以获取
match_results
对象。
因此,您可以使用以下内容来获取匹配项及其位置:
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main() {
std::regex r(R"(\w)");
std::string s("a,b,c,d,e,f,g");
for(std::sregex_iterator i = std::sregex_iterator(s.begin(), s.end(), r);
i != std::sregex_iterator();
++i)
{
std::smatch m = *i;
std::cout << "Match value: " << m.str() << " at Position " << m.position() << '\n';
}
return 0;
}
请参阅IDEONE demo
结果:
Match value: a at Position 0
Match value: b at Position 2
Match value: c at Position 4
Match value: d at Position 6
Match value: e at Position 8
Match value: f at Position 10
Match value: g at Position 12
使用原始字符串文字更好地声明正则表达式(R"(\w)"
是\w
正则表达式模式)。