主页 > 教程合集 > 工具推荐 >

C++正则匹配HTML标签input实例

时间:2021-02-02 阅读:0

c++正则匹配HTML标签input实例,c++实例。

C++正则匹配HTML标签input实例

文件demo.html


<!--这里设置一个重复的 id ,并且有一对单引号-->
<input type="hidden" value="hk" id='888' id='languageId'/>
 
<input type="hidden" value=" " id="topNavPreviewId"/>
 
<form action="transfers.htm" autocomplete="off" method="get" id="searchForm">
        <input class="gnav-bar-search-input" name="keyword" id="keyword" placeholder="搜索" autocomplete="off" autocorrect="off" required="">
        <button type="button" class="gnav-bar-search-clear fa fa-times"></button>
</form>
<input type="hidden" id="productName" value="Air Jordan XXXV CNY PF">
<input type="hidden" id="productLabel" value="男子籃球鞋">
 

文件 t_html.cpp


/**
  * 通过正则表达式提取指定标签
  * @Author: mrdede <3444056@qq.com>
  * @Blog: http://mrdede.com/
  * @Time: 2021/1/31 21:47
  *
  * Copyright (c) 2021 织梦先生. All rights reserved.
  *
  * g++ t_html.cpp -o t_html.exe
  *
  */

 
// ┌─┬─┐
// ├ ┼ ┤ │
// └─┴─┘
 
#include <iostream>
#include <cstring>
#include <ctime>
 
#include <fstream>
#include <regex>
//#include <algorithm>// 算法
 
void title(std::string title) {
        std::cout << "\n\n\n";
        int total = 0;
        int tmp;
        for (std::string::iterator it = title.begin(); it < title.end(); it++) {
                tmp = it.operator*();
                if (tmp < 0) {
                        total += 2;
                        // UTF8编码的汉字是3字节,所以这里+2,下一循环则迭代下一个字符
                        it += 2;
                } else {
                        total += 1;
                }
        }
        std::cout << std::endl;
        std::string _out;
        for (int i = 0; i < total; i++) {
                _out += "─";
        }
        std::cout << " ┌─" << _out << "─┐" << std::endl;
        std::cout << "----------│ " << title << " │" << std::endl;
        std::cout << " └─" << _out << "─┘" << std::endl;
 
}
 
/**
  * 获取文件内容字符串
  * @param file_content
  */

void getFileContent(std::string &file_content) {
        FILE *fp;
        long int l_size;
        char *sz_buf;
 
        fp = fopen("demo.html", "r");
        if (fp) {
                // fseek() : 用来移动文件流的读写位置
                fseek(fp, 0, SEEK_END); // 读取位置移动到文件结尾
                // long int ftell(FILE *stream)
                l_size = ftell(fp); // 返回给定流 stream 的当前文件位置
                fseek(fp, 0, SEEK_SET); // 读取位置再移动到文件开头
                sz_buf = new char[l_size + 1];
                fread(sz_buf, 1, l_size, fp); // 从给定流 stream 读取数据到 sz_buf 所指向的数组中
                fclose(fp); // 关闭文件
                sz_buf[l_size] = 0; // TODO 这是什么意思,不明白
                // 读取文件内容保存到string
                file_content = sz_buf;
                delete sz_buf; // 释放 new 分配的单个对象指针指向的内存
 
        }
 
}
 
// 保存匹配到的 input 的结构体
struct struct_input {
        std::string src; // 匹配到的input源码
        std::map<std::string, std::string> attribute; // 属性
};
 
/**
  * 匹配并保存字符串
  * @param inputs 保存匹配到的 input 字符串的集合
  * @param file_content 文本内容,字符串
  */

void getTagInputs(std::vector<std::string> &inputs, std::string &file_content) {
 
        // 提取
        std::smatch mat_input;
        std::smatch mat_attribute;
        std::string attribute_name;
        std::string attribute_val;
        std::regex reg_input("<input([^>]+)/?>");
        // 属性值使用单引号和双引号都可以匹配
        std::regex reg_input_attribute(" (\\w+)=\"([^\"]*)\"| (\\w+)=\'([^\']*)\'");
 
        // 迭代器
        std::string::const_iterator start = file_content.begin();
        std::string::const_iterator end = file_content.end();
        std::string::const_iterator start2;
        std::string::const_iterator end2;
 
        int index = 0; /////
        while (regex_search(start, end, mat_input, reg_input)) {
                // mat_input[0] 匹配的整个字符串
                // mat_input[1] 第一个括号匹配的字符串
                std::cout << "-- mat_input[0]:\t" << mat_input[0] << std::endl; /////
                std::string msg(mat_input[1].first, mat_input[1].second);
 
                start2 = msg.begin();
                end2 = msg.end();
 
                int index2 = 0; /////
 
                // 如果存在重复的属性名称,后一个值会覆盖前一个值的
                while (regex_search(start2, end2, mat_attribute, reg_input_attribute)) {
                        attribute_name = mat_attribute[1]; // 双引用匹配
                        // 如果双引用匹配不到,则使用单引号匹配的值
                        if (attribute_name.empty()) { // 单引用匹配
                                attribute_name = mat_attribute[3];
                                attribute_val = mat_attribute[4];
                        } else { // 双引用匹配
                                attribute_val = mat_attribute[2];
                        }
                        std::cout << index2 << "\tname:\t" << attribute_name << "\tval:\t" << attribute_val << std::endl; /////
                        start2 = mat_attribute[0].second;
                        index2++;
                }
                inputs.push_back(msg);
                start = mat_input[0].second;
 
                index++; /////
                if (index > 3) break; ///// 测试时只循环4次
        }
 
}
 
/**
  * 匹配并保存input结构体
  * @param inputs 保存匹配到的 input 结构体的集合
  * @param file_content 文本内容,字符串
  */

void getTagInputs2(std::vector<struct_input> &inputs, std::string &file_content) {
 
        // 提取
        struct_input temp_su_input;
        std::smatch mat_input;
        std::smatch mat_attribute;
        std::string attribute_name;
        std::string attribute_val;
        std::regex reg_input("<input([^>]+)/?>");
        // 属性值使用单引号和双引号都可以匹配
        std::regex reg_input_attribute(" (\\w+)=\"([^\"]*)\"| (\\w+)=\'([^\']*)\'");
 
        // 迭代器
        std::string::const_iterator start = file_content.begin();
        std::string::const_iterator end = file_content.end();
        std::string::const_iterator start2;
        std::string::const_iterator end2;
 
        int index = 0; /////
        while (regex_search(start, end, mat_input, reg_input)) {
                // mat_input[0] 匹配的整个字符串
                // mat_input[1] 第一个括号匹配的字符串
                std::cout << "-- mat_input[0]:\t" << mat_input[0] << std::endl; /////
                std::string msg(mat_input[1].first, mat_input[1].second);
 
                start2 = msg.begin();
                end2 = msg.end();
                std::map<std::string, std::string> attribute; // 保存属性名值对
 
                int index2 = 0; /////
 
                // 如果存在重复的属性名称,后一个值会覆盖前一个值的
                while (regex_search(start2, end2, mat_attribute, reg_input_attribute)) {
                        attribute_name = mat_attribute[1]; // 双引用匹配
                        // 如果双引用匹配不到,则使用单引号匹配的值
                        if (attribute_name.empty()) { // 单引用匹配
                                attribute_name = mat_attribute[3];
                                attribute_val = mat_attribute[4];
                        } else { // 双引用匹配
                                attribute_val = mat_attribute[2];
                        }
                        attribute[attribute_name] = attribute_val;
                        std::cout << index2 << "\tname:\t" << attribute_name << "\tval:\t" << attribute_val << std::endl; /////
                        start2 = mat_attribute[0].second;
                        index2++;
                }
 
                temp_su_input.src = mat_input[0];
                temp_su_input.attribute = attribute;
                inputs.push_back(temp_su_input);
 
                start = mat_input[0].second; // 调整迭代器起始位置
 
                index++; /////
                if (index > 3) break; /////
        }
 
}
 
// 正则提取HTML中的input标签元素
int test01(std::string param) {
        /**
          * 输出:
                vector<string> length: 67
                -- 提取工作用时:63 ms
                -- 用时:78 ms
          *
          */

        title("正则提取HTML中的input标签元素");
 
        std::string file_str;
        getFileContent(file_str); // 获取文件内容
 
        if (!file_str.empty()) {
                std::vector<std::string> inputs;
 
                clock_t start_time = clock(); // 计时开始
 
                getTagInputs(inputs, file_str); // 获取 input 标签
 
                std::cout << "vector<string> length:\t" << inputs.size() << std::endl;
 
                clock_t end_time = clock(); // 计时结束
                std::cout << "-- 提取工作用时:" << end_time - start_time << " ms" << std::endl;
 
        }
 
        /*FILE *fp;
        long int l_size;
        char *sz_buf;
 
        fp = fopen("demo.html", "r");
        if (fp) {
               // fseek() : 用来移动文件流的读写位置
                fseek(fp, 0, SEEK_END);// 读取位置移动到文件结尾
               // long int ftell(FILE *stream)
                l_size = ftell(fp);// 返回给定流 stream 的当前文件位置
                fseek(fp, 0, SEEK_SET);// 读取位置再移动到文件开头
                sz_buf = new char[l_size + 1];
                fread(sz_buf, 1, l_size, fp);// 从给定流 stream 读取数据到 sz_buf 所指向的数组中
                fclose(fp);// 关闭文件
                sz_buf[l_size] = 0;// TODO 这是什么意思,不明白
               // 读取文件内容保存到string
                file_str = sz_buf;
                delete sz_buf;// 释放 new 分配的单个对象指针指向的内存
 
                clock_t start_time = clock();// 计时开始
               // 提取
                std::vector<std::string> inputs;
                std::smatch mat;
                std::regex _input("<input([^>]+)/?>");
 
               // 迭代器
                std::string::const_iterator start = file_str.begin();
                std::string::const_iterator end = file_str.end();
 
                while (regex_search(start, end, mat, _input)) {
                        std::string msg(mat[1].first, mat[1].second);
                        inputs.push_back(msg);
                        start = mat[0].second;
                }
 
                std::cout << "vector<string> length:\t" << inputs.size() << std::endl;
 
                clock_t end_time = clock();// 计时结束
                std::cout << "-- 提取工作用时:" << end_time - start_time << " ms" << std::endl;
 
        }*/

 
        return 0;
}
 
// 正则提取HTML中的input标签元素,并压入容器
int test02(std::string param) {
        title("正则提取HTML中的input标签元素,并压入容器");
 
        std::string file_str;
        getFileContent(file_str); // 获取文件内容
 
        if (!file_str.empty()) {
                std::vector<struct_input> inputs;
 
                clock_t start_time = clock(); // 计时开始
 
                getTagInputs2(inputs, file_str); // 获取 input 标签
 
                std::cout << "vector<string> length:\t" << inputs.size() << std::endl;
 
                clock_t end_time = clock(); // 计时结束
                std::cout << "-- 提取工作用时:" << end_time - start_time << " ms" << std::endl;
 
                // 验证获取的结构体是否正确
                std::cout << "\n-- 验证提取结果:" << std::endl;
                for (auto &it : inputs) {
                        std::cout << "-- it.src:\t" << it.src << std::endl; /////
                        for (auto &it2 : it.attribute) {
                                std::cout << "name:\t" << it2.first << "\tval:\t" << it2.second << std::endl; /////
                        }
                }
        }
 
        return 0;
}
 
int main(int argc, char *argv[]) {
        std::cout << "-- argc:\t\t" << argc << std::endl;
        for (int i = 0; i < argc; i++) {
                std::cout << "-- argv[" << i << "]:\t" << argv[i] << std::endl;
        }
        std::cout << "" << std::endl;
 
        clock_t start_time = clock(); // 计时开始
 
        int av1 = argc > 1 ? atoi(argv[1]) : 0;
        std::string av2 = argc > 2 ? argv[2] : "";
        switch (av1) {
                case 1:
                        test01(av2);
                        break;
                case 2:
                        test02(av2);
                        break;
                default:
                        test01(av2);
                        test02(av2);
                        break;
        }
 
        clock_t end_time = clock(); // 计时结束
        std::cout << "-- 全局用时:" << end_time - start_time << " ms" << std::endl;
 
        return 0;
}
 

开通特权,即可免费下载全站所有千余TB网络资源,点击 >>> 资源目录 查看所有资源,覆盖音乐、影视、有声书、电子书、漫画、动漫、课程等,不限时间次数,永久免费,点击 >>> 特权详情 了解更多!

余斗余斗
  • 版权声明:原创文章由发表在工具推荐分类下,2021-02-02最后更新,转载注明出处。

相关推荐

返回顶部