我正在使用带有Boost Regex/Xpressive的命名捕获组。
我想遍历所有子匹配项,并获取每个子匹配项的值和KEY(即what [“type”])。
sregex pattern = sregex::compile( "(?P<type>href|src)=\"(?P<url>[^\"]+)\"" );
sregex_iterator cur( web_buffer.begin(), web_buffer.end(), pattern );
sregex_iterator end;
for( ; cur != end; ++cur ){
smatch const &what = *cur;
//I know how to access using a string key: what["type"]
std::cout << what[0] << " [" << what["type"] << "] [" << what["url"] <<"]"<< std::endl;
/*I know how to iterate, using an integer key, but I would
like to also get the original KEY into a variable, i.e.
in case of what[1], get both the value AND "type"
*/
for(i=0; i<what.size(); i++){
std::cout << "{} = [" << what[i] << "]" << std::endl;
}
std::cout << std::endl;
}
最佳答案
使用Boost 1.54.0时,这甚至更加困难,因为捕获名称甚至没有存储在结果中。相反,Boost只是对捕获名称进行哈希处理,并存储哈希(int
)和指向原始字符串的关联指针。
我编写了一个从boost::smatch
派生的小类,该类保存捕获名称并为其提供迭代器。
class namesaving_smatch : public smatch
{
public:
namesaving_smatch(const regex& pattern)
{
std::string pattern_str = pattern.str();
regex capture_pattern("\\?P?<(\\w+)>");
auto words_begin = sregex_iterator(pattern_str.begin(), pattern_str.end(), capture_pattern);
auto words_end = sregex_iterator();
for (sregex_iterator i = words_begin; i != words_end; i++)
{
std::string name = (*i)[1].str();
m_names.push_back(name);
}
}
~namesaving_smatch() { }
std::vector<std::string>::const_iterator names_begin() const
{
return m_names.begin();
}
std::vector<std::string>::const_iterator names_end() const
{
return m_names.end();
}
private:
std::vector<std::string> m_names;
};
该类在其构造函数中接受包含命名捕获组的正则表达式。像这样使用类:
namesaving_smatch results(re);
if (regex_search(input, results, re))
for (auto it = results.names_begin(); it != results.names_end(); ++it)
cout << *it << ": " << results[*it].str();
关于C++::Boost::Regex迭代子匹配项,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2718607/