2014-11-23 46 views
1

我正在阅读关于std::regex_iterator<std::string::iterator>的文档,因为我试图学习如何使用它来解析HTML标记。该网站给出的例子是根据CPlusPlus.com使用std :: regex_iterator <std :: string :: iterator>

#include <iostream> 
#include <string> 
#include <regex> 

int main() 
{ 
    std::string s ("this subject has a submarine as a subsequence"); 
    std::regex e ("\\b(sub)([^ ]*)"); // matches words beginning by "sub" 

    std::regex_iterator<std::string::iterator> rit (s.begin(), s.end(), e); 
    std::regex_iterator<std::string::iterator> rend; 

    while (rit!=rend) { 
    std::cout << rit->str() << std::endl; 
    ++rit; 
    } 

    return 0; 
} 

http://www.cplusplus.com/reference/regex/regex_iterator/regex_iterator/

和我有一个问题:如果rend从未初始化,那么它是如何被有意义的rit!=rend使用?

此外,我应该用什么工具获取HTML标签的属性?我想要做的就是有一个字符串像"class='class1 class2' id = 'myId' onclick ='myFunction()' >"并打破成对

"class""class1 class2"),("id""myId"),("onclick""myFunction()"

,然后与他们从那里工作。正则表达式我打算用的是

([A-Za-z0-9\\-]+)\\s*=\\s*(['\"])(.*?)\\2 

,所以我打算通过这种类型的表达式循环遍历同时跟踪我是否仍然在标签(即,是否我通过一个'>'字符)。这样做太难了吗?

感谢您为我提供的任何指导。

回答

3

你是什么意思“如果rend永远不会初始化”?显然,std::regex_iterator<I>有一个默认的构造函数。由于迭代只是前向迭代,所以结束迭代器只需要适合检测结束就可以使用。默认构造函数可以相应地设置rend

这是在标准C++库中的其他地方使用的一个习语,例如std::istream_iterator<T>。理想情况下,可以使用不同类型指示结束迭代器(有关此问题,请参阅Eric Niebler's discussion,链接是四页中的第一页),但标准当前要求使用算法时两种类型匹配。

关于使用正则表达式解析HTML请参阅this answer

1

rend不是未初始化的,它是默认构造的。您链接的页面明确指出:

默认构造函数(1)构造序列结束迭代器。

由于缺省结构似乎是获得结束序列的迭代器的唯一办法,比较ritrend是测试rit是否耗尽的正确方法。

相关问题