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