{
    分享网正式开通,我们为大家提供免费资源,欢迎大家踊跃投稿!

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

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

文件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



 
// ┌─┬─┐
// ├ ┼ ┤ │
// └─┴─┘
 
#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;
 
}
 

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; // 属性
};
 

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次
        }
 
}
 

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) {
       
        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;
 
        }
 
       
 
        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;
}
 
资源均来自第三方,谨慎下载,前往第三方网站下载


米微资源分享网 , 版权所有丨本站资源仅限于学习研究,严禁从事商业或者非法活动!丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:C++正则匹配HTML标签input实例
喜欢 ()分享 (0)