C ++ :: Boost :: Regex Iterate over the sub-matrices

I am using Named Capture Groups with Boost Regex / Xpressive.

I would like to iterate over all the submatrices and get both the value and KEY of each swap (that is, that ["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;
}
+5
source share
2 answers

With Boost 1.54.0, this is even more complicated because capture names are not even stored in the results. Instead, Boost simply hashes the capture names and stores the hash (a int) and associated pointers to the source string.

I wrote a small class derived from boost::smatchthat stores the names of the captures and provides an iterator for them.

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();
+3

, , : " ". , _____________________________________________ , . , , , , , , .

const_reference at_(char_type const *name) const
{
    for(std::size_t i = 0; i < this->named_marks_.size(); ++i)
    {
        if(this->named_marks_[i].name_ == name)
        {
            return this->sub_matches_[ this->named_marks_[i].mark_nbr_ ];
        }
    }
    BOOST_THROW_EXCEPTION(
        regex_error(regex_constants::error_badmark, "invalid named back-reference")
    );
    // Should never execute, but if it does, this returns
    // a "null" sub_match.
    return this->sub_matches_[this->sub_matches_.size()];
}
+2

All Articles