C++ 提取网页内容系列之四正则

标 题: C++ 提取网页内容系列之四
作 者: itdef
链 接: http://www.cnblogs.com/itdef/p/4173833.html 

欢迎转帖 请保持文本完整并注明出处


将网页内容下载后存入字符串string 或者本地文件后 我们开始进行搜索和查询 获取信息
这里使用正则式  使用vs2008  其自带的tr1库(预备标准库) 有正则式库供使用
带头文件/*******************************************************************************
*  @file        
*  @author      def< qq group: 324164944 >
*  @blog        http://www.cnblogs.com/itdef/
*  @brief     
/*******************************************************************************/
#include <regex>
using namespace std::tr1;
using namespace std;

这里推荐正则式教程
正则表达式30分钟入门教程
http://www.cnblogs.com/deerchao/ ... zhongjiaocheng.html

C++:Regex正则表达式
http://blog.sina.com.cn/s/blog_ac9fdc0b0101oow9.html

 

首先来个简单例子

复制代码
#include <string>
#include <iostream>
#include <regex>

using namespace std::tr1;
using namespace std;

string strContent = " onclick=\"VeryCD.TrackEvent('base', '首页大推', '神雕侠侣');";

void Test1()
{
        string strText = strContent;
        string strRegex = "首页大推";
        regex regExpress(strRegex);

        smatch ms;

        cout << "*****************************" << endl;
        cout << "Test 1" << endl << endl;

        while(regex_search(strText, ms, regExpress))
        {
                for(string::size_type i = 0;i < ms.size();++i)
                {
                        cout << ms.str(i).c_str() << endl;
                }
                strText = ms.suffix().str();
        }

        cout << "*****************************" << endl << endl;
}

void Test2()
{
        string strText = strContent;
        string strRegex = "首页大推.*'(.*)'";
        regex regExpress(strRegex);

        smatch ms;

        cout << "*****************************" << endl;
        cout << "Test 2" << endl << endl;
        while(regex_search(strText, ms, regExpress))
        {
                for(string::size_type i = 0;i < ms.size();++i)
                {
                        cout << ms.str(i).c_str() << endl;
                }
                strText = ms.suffix().str();
        }
        cout << "*****************************" << endl << endl;
}


int _tmain(int argc, _TCHAR* argv[])
{
        Test1();
        Test2();
                
        return 0;
}
复制代码

Test1中 我们等于是直接搜索字符串 然后 打印出找到的位置Test2中 我们使用 首页大推.*'(.*)'  
.号等于是任意非空白换行字符 *则代表重复任意多次(0-无穷次)
而括号表示一个字符集 也就是我们需要查找的内容 
请注意这个括号是在 ' '  之间的  也就是查找 首页大推 任意字符之后 两个 '  '号之间的内容

效果如下:
而且我们也发现 ms的显示规律 他首先显示符合条件的字符串 然后现实符合( )里面条件的子字符串

 

下面来个深入点得  分析这个字符串
string strContent0 = "alt=\"火影忍者\" /><div class=\"play_ico_middle\"></div><div class=\"cv-title\" style=\"width:85px;\">更新至612集</div>";

我们使用的正则式规则为 string strRegex = "alt=\"([^\"]*)\".*width:85px;\">(.*)</div>";
注意里面有两个括号  一个是在alt= 之后 在两个" " 之间的内容  一个是在width:85px;\">  和 </div> 之间的内容 
注意  "的显示 由于C++语言的特性 必须写成 \"
现在分析两个括号内容 ([^\"]*)     (.*)

(.*)无须多说  就是任意非空白字符 而且是在width:85px;\">  和 </div> 之间的内容 
([^\"]*)  就是说 非"的内容任意重复多次  而且这个括号是在alt= 之后 在两个" " 之间的内容

运行结果如下:(为了不显示过多内容 符合条件的内容没有全部显示 只显示了符合括号需求的子字符串)

 

复制代码
/*******************************************************************************
*  @file        
*  @author      def< qq group: 324164944 >
*  @blog        http://www.cnblogs.com/itdef/
*  @brief     
/*******************************************************************************/


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

using namespace std::tr1;
using namespace std;



string strContent = " onclick=\"VeryCD.TrackEvent('base', '首页大推', '神雕侠侣');";

string strContent0 = "alt=\"火影忍者\" /><div class=\"play_ico_middle\"></div><div class=\"cv-title\" style=\"width:85px;\">更新至612集</div>";

void Test1()
{
        string strText = strContent;
        string strRegex = "首页大推";
        regex regExpress(strRegex);

        smatch ms;

        cout << "*****************************" << endl;
        cout << "Test 1" << endl << endl;

        while(regex_search(strText, ms, regExpress))
        {
                for(string::size_type i = 0;i < ms.size();++i)
                {
                        cout << ms.str(i).c_str() << endl;
                }
                strText = ms.suffix().str();
        }

        cout << "*****************************" << endl << endl;
}

void Test2()
{
        string strText = strContent;
        string strRegex = "首页大推.*'(.*)'";
        regex regExpress(strRegex);

        smatch ms;

        cout << "*****************************" << endl;
        cout << "Test 2" << endl << endl;
        while(regex_search(strText, ms, regExpress))
        {
                for(string::size_type i = 0;i < ms.size();++i)
                {
                        cout << ms.str(i).c_str() << endl;
                }
                strText = ms.suffix().str();
        }
        cout << "*****************************" << endl << endl;
}

void Test3()
{
        string strText = strContent0;
        string strRegex = "alt=\"([^\"]*)\".*width:85px;\">(.*)</div>";
        regex regExpress(strRegex);

        smatch ms;

        cout << "*****************************" << endl;
        cout << "Test 3" << endl << endl;

        while(regex_search(strText, ms, regExpress))
        {
                for(string::size_type i = 0;i < ms.size();++i)
                {
                        if(i > 0)
                                cout << ms.str(i).c_str() << endl;
                }
                strText = ms.suffix().str();
        }
        cout << "*****************************" << endl << endl;

}


int _tmain(int argc, _TCHAR* argv[])
{
        Test1();
        Test2();
        Test3();
                
        return 0;
}
复制代码

 

posted on   itdef  阅读(2937)  评论(0编辑  收藏  举报

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示