С 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();