C++ 正则库与HTTP请求

正则表达式的概念和语法

用于描述和匹配字符串的工具,通过特定的语法规则,灵活的定义复杂字符串匹配条件

常用语法总结

  • 基本字符匹配

    • a:匹配字符'a'
    • abc:匹配字符串'abc'
  • 元字符(特殊含义的字符)

    • .:匹配任意单个字符(除了换行符)
    • ^:匹配字符串的开始位置
    • $:匹配字符串的结束位置
    • *:匹配前面的元素零次或多次
    • +:匹配前面的元素一次或多次
    • ?:匹配前面的元素零次或一次
    • |:表示逻辑“或”操作
    • \:转义字符,用于匹配特殊字符
  • 字符类(匹配一组字符中的任意一个

    • [abc]:匹配'a'、'b'或'c'
    • [a-z]:匹配所有小写字母
    • [^abc]:匹配除'a'、'b'、'c'之外的任意字符
  • 预定义字符类

    • \d:匹配任何数字,等价于[0-9]
    • \D:匹配任何非数字字符
    • \w:匹配任何字母、数字或下划线,等价于[a-zA-Z0-9_]
    • \W:匹配任何非字母、数字或下划线字符
    • \s:匹配任何空白字符(空格、制表符等)
    • \S:匹配任何非空白字符
  • 重复限定符

    • {n}:匹配前面的元素恰好n次
    • {n,}:匹配前面的元素至少n次
    • {n,m}:匹配前面的元素至少n次,至多m次
  • 分组与捕获(分组和捕获匹配的字符串)

    • (abc):匹配'abc',并捕获该匹配
    • (?:abc):匹配'abc',但不捕获该匹配
  • 断言(匹配位置)

    • (?=...):正向先行断言,要求后面的字符必须匹配
    • (?!...):负向先行断言,要求后面的字符不能匹配
    • (?<=...):正向后行断言,要求前面的字符必须匹配
    • (?<!...):负向后行断言,要求前面的字符不能匹配

 

使用

 创建正则表达式对象

正则匹配(检查是否一致);正则搜索(只要包含即可) 

 

正则替换:通过正则表达式,对字符串中的字符进行更换 

 

提取匹配的子字符串,提取的子字符串都存储在了smatch中 

 

处理异常:使用try_catch捕获异常 

 

测试代码汇总 

#include <iostream>
#include <regex>
#include <string>int main()
{// std::regex pattern("abc");//正则匹配// std::string str = "abcddfd";// if(std::regex_match(str,pattern))// {//     std::cout<<"match fount"<<std::endl;// }// else // {//     std::cout<<"match not found"<<std::endl;// }// //正则搜索(只要有查询的字符即可)// if(std::regex_search(str,pattern))// {//     std::cout<<"search found"<<std::endl;// }// else// {//     std::cout<<"search not fount"<<std::endl;// }// //正则替换// std::string replaced = std::regex_replace(str,pattern,"mmm");// std::cout<<replaced<<std::endl;//提取匹配的子字符串std::string str1 = "abc123";std::regex pattern("(abc)(\\d+)");std::smatch matches;if(std::regex_search(str1,matches,pattern)){for(size_t i =0;i<matches.size();i++){std::cout << "Match " << i << ": " << matches[i].str() << std::endl;}}return 0;
}

HTTP解析和响应 

解析请求分析

 

([A-Z]+)

  • [A-Z]:匹配单个大写字母。
  • +:匹配前面的字符一次或多次,即匹配一个或多个大写字母。
  • ():捕获组,用于提取匹配的子字符串。
  • 这个部分匹配HTTP方法,如 GETPOSTPUT 等。

(.+)

  • .:匹配任意单个字符(除换行符外)。
  • +:匹配前面的字符一次或多次,即匹配一个或多个任意字符。
  • ():捕获组,用于提取匹配的子字符串。
  • 这个部分匹配请求的路径,如 /index.html

HTTP/([0-9\\.]+)

  • HTTP/:匹配字符串 HTTP/
  • [0-9\\.]:匹配数字(0-9)或点号(.)。
  • +:匹配前面的字符一次或多次,即匹配一个或多个数字或点号。
  • ():捕获组,用于提取匹配的子字符串。
  • 这个部分匹配HTTP版本号,如 1.1

\r\n

  • \r:匹配回车符。
  • \n:匹配换行符。
  • 这个部分匹配HTTP请求行的结尾。

 解析头部字段

([A-Za-z-]+)

  • [A-Za-z-]:匹配单个字母(大小写皆可)或连字符。
  • +:匹配前面的字符一次或多次,即匹配一个或多个字母或连字符。
  • ():捕获组,用于提取匹配的子字符串。
  • 这个部分匹配头部字段的名称,如 HostUser-AgentAccept

  • 匹配冒号和一个空格,作为头部字段名称与值的分隔符。

(.+)

  • .:匹配任意单个字符(除换行符外)。
  • +:匹配前面的字符一次或多次,即匹配一个或多个任意字符。
  • ():捕获组,用于提取匹配的子字符串。
  • 这个部分匹配头部字段的值,如 www.example.comcurl/7.68.0*/* 等。

/r/n

  • \r:匹配回车符。
  • \n:匹配换行符。
  • 这个部分匹配头部字段行的结尾

 

构成响应

  • 构建状态行:HTTP版本+状态码+状态描述符
  • 构建头部字段:遍历headers哈希表,将其加入到响应字符串职工
  • 构建响应体:头部字段后添加一个空行\r\n,然后追加响应体内容 

 

完整测试代码

#include <iostream>
#include <regex>
#include <string>
#include <map>struct HttpRequest {std::string method;std::string path;std::string version;std::map<std::string, std::string> headers;std::string body;
};HttpRequest parseHttpRequest(const std::string& request) {HttpRequest httpRequest;std::regex requestLinePattern("([A-Z]+) (.+) HTTP/([0-9\\.]+)\r\n");std::regex headerPattern("([A-Za-z-]+): (.+)\r\n");std::smatch matches;// 解析请求行if (std::regex_search(request, matches, requestLinePattern)) {httpRequest.method = matches[1].str();httpRequest.path = matches[2].str();httpRequest.version = matches[3].str();}// 解析头部字段auto headersBegin = std::sregex_iterator(request.begin(), request.end(), headerPattern);auto headersEnd = std::sregex_iterator();for (std::sregex_iterator i = headersBegin; i != headersEnd; ++i) {std::smatch match = *i;httpRequest.headers[match[1].str()] = match[2].str();}// 查找请求体的开始位置size_t bodyPos = request.find("\r\n\r\n");if (bodyPos != std::string::npos) {httpRequest.body = request.substr(bodyPos + 4);}return httpRequest;
}std::string generateHttpResponse(const std::string& status, const std::map<std::string, std::string>& headers, const std::string& body) {std::string response = "HTTP/1.1 " + status + "\r\n";for (const auto& header : headers) {response += header.first + ": " + header.second + "\r\n";}response += "\r\n" + body;return response;
}int main() {std::string request = "GET /index.html HTTP/1.1\r\nHost: www.example.com\r\nUser-Agent: curl/7.68.0\r\nAccept: */*\r\n\r\n";// 解析HTTP请求HttpRequest httpRequest = parseHttpRequest(request);// 打印解析结果std::cout << "Method: " << httpRequest.method << std::endl;std::cout << "Path: " << httpRequest.path << std::endl;std::cout << "Version: " << httpRequest.version << std::endl;for (const auto& header : httpRequest.headers) {std::cout << header.first << ": " << header.second << std::endl;}std::cout << "Body: " << httpRequest.body << std::endl;// 生成HTTP响应std::map<std::string, std::string> headers = {{"Content-Type", "text/html"},{"Content-Length", "13"}};std::string body = "<h1>Hello</h1>";std::string response = generateHttpResponse("200 OK", headers, body);// 打印响应报文std::cout << response << std::endl;return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/49221.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1Panel面板配置java运行环境及网站的详细操作教程

本篇文章主要讲解&#xff0c;通过1Panel面板实现java运行环境&#xff0c;部署网站并加载的详细教程。 日期&#xff1a;2024年7月21日 作者&#xff1a;任聪聪 独立博客&#xff1a;https://rccblogs.com/501.html 一、实际效果 二、详细操作 步骤一、给我的项目进行打包&am…

在jsPsych中使用Vue

jspsych 介绍 jsPsych是一个非常好用的心理学实验插件&#xff0c;可以用来构建心理学实验。具体的就不多介绍了&#xff0c;大家可以去看官网&#xff1a;https://www.jspsych.org/latest/ 但是大家在使用时就会发现&#xff0c;这个插件只能使用js绘制界面&#xff0c;或者…

STM32自己从零开始实操10:PCB全过程

一、PCB总体分布 分布主要参考有&#xff1a; 方便供电布线。方便布信号线。方便接口。人体工学。 以下只能让大家看到各个模块大致分布在板子的哪一块&#xff0c;只能说每个人画都有自己的理由&#xff0c;我的理由如下。 还有很多没有表达出来的东西&#xff0c;我也不知…

PingCAP 王琦智:下一代 RAG,tidb.ai 使用知识图谱增强 RAG 能力

导读 随着 ChatGPT 的流行&#xff0c;LLMs&#xff08;大语言模型&#xff09;再次进入人们的视野。然而&#xff0c;在处理特定领域查询时&#xff0c;大模型生成的内容往往存在信息滞后和准确性不足的问题。如何让 RAG 和向量搜索技术在实际应用中更好地满足企业需求&#…

昇思25天学习打卡营第14天|计算机视觉

昇思25天学习打卡营第14天 文章目录 昇思25天学习打卡营第14天FCN图像语义分割语义分割模型简介网络特点数据处理数据预处理数据加载训练集可视化 网络构建网络流程 训练准备导入VGG-16部分预训练权重损失函数自定义评价指标 Metrics 模型训练模型评估模型推理总结引用 打卡记录…

FPGA开发在verilog中关于阻塞和非阻塞赋值的区别

一、概念 阻塞赋值&#xff1a;阻塞赋值的赋值号用“”表示&#xff0c;对应的是串行执行。 对应的电路结构往往与触发沿没有关系&#xff0c;只与输入电平的变化有关系。阻塞赋值的操作可以认为是只有一个步骤的操作&#xff0c;即计算赋值号右边的语句并更新赋值号左边的语句…

Transformer-Bert---散装知识点---mlm,nsp

本文记录的是笔者在了解了transformer结构后嗑bert中记录的一些散装知识点&#xff0c;有时间就会整理收录&#xff0c;希望最后能把transformer一个系列都完整的更新进去。 1.自监督学习 bert与原始的transformer不同&#xff0c;bert是使用大量无标签的数据进行预训…

规范:前后端接口规范

1、前言 随着互联网的高速发展&#xff0c;前端页面的展示、交互体验越来越灵活、炫丽&#xff0c;响应体验也要求越来越高&#xff0c;后端服务的高并发、高可用、高性能、高扩展等特性的要求也愈加苛刻&#xff0c;从而导致前后端研发各自专注于自己擅长的领域深耕细作。 然…

volatile,最轻量的同步机制

目录 一、volatile 二、如何使用&#xff1f; 三、volatile关键字能代替synchronized关键字吗&#xff1f; 四、总结&#xff1a; 还是老样子&#xff0c;先来看一段代码&#xff1a; 我们先由我们自己的常规思路分析一下代码&#xff1a;子线程中&#xff0c;一直循环&…

NoSQL之Redis非关系型数据库

目录 一、数据库类型 1&#xff09;关系型数据库 2&#xff09;非关系型数据库 二、Redis远程字典服务器 1&#xff09;redis介绍 2&#xff09;redis的优点 3&#xff09;Redis 为什么那么快&#xff1f; 4&#xff09;Redis使用场景 三、Redis安装部署 1&#xff0…

kail-linux如何使用NAT连接修改静态IP

1、Contos修改静态IP vi /etc/sysconfig/network-scripts/ifcfg-ens33&#xff0c; 标记红色处可能序号会变动 参考linux配置网络不通解决方案_kylinv10sp2 网关不通-CSDN博客https://tanrt06.blog.csdn.net/article/details/132430485?spm1001.2014.3001.5502 Kail时候NAT连…

从 NextJS SSRF 漏洞看 Host 头滥用所带来的危害

前言 本篇博文主要内容是通过代码审计以及场景复现一个 NextJS 的安全漏洞&#xff08;CVE-2024-34351&#xff09;来讲述滥用 Host 头的危害。 严正声明&#xff1a;本博文所讨论的技术仅用于研究学习&#xff0c;旨在增强读者的信息安全意识&#xff0c;提高信息安全防护技能…

浅谈断言之XML Schema断言

浅谈断言之XML Schema断言 “XML Schema断言”是一种专门用于验证基于XML的响应是否遵循特定XML Schema定义的标准和结构的断言类型。下面我们将详细探讨XML Schema断言的各个方面。 XML Schema断言简介 XML Schema断言&#xff08;XML Schema Assertion&#xff09;允许用户…

fastJSON 解决kafka消息斜杠转义问题

Bug: kafka发送消息时的JSON转义异常 问题描述: 问题描述:kafka消息发送出去但是消费者执行相关逻辑的时候报错. 场景:当时实习的时候需要模拟数据做一个实时经纬度传输的接口,使用kafka实时发送消息将数据同步到数据库中 问题分析: fastjson使用不当可能导致转义异常**,kafka…

Android 15 之如何快速适配 16K Page Size

在此之前&#xff0c;我们通过 《Android 15 上 16K Page Size 为什么是最坑》 介绍了&#xff1a; 什么是16K Page Size为什么它对于 Android 很坑如何测试 如果你还没了解&#xff0c;建议先去了解下前文&#xff0c;然后本篇主要是提供适配的思路&#xff0c;因为这类适配…

Facebook Dating:社交平台的约会新体验

随着社交媒体的普及和技术的发展&#xff0c;传统的社交方式正在经历革新&#xff0c;尤其是在约会这个领域。Facebook作为全球领先的社交平台&#xff0c;推出了Facebook Dating&#xff0c;旨在为用户提供一个全新的约会体验。本文将探讨Facebook Dating如何重新定义社交平台…

43 华三AC登录Web页面

一 无线上WEB页面 1 创建vlan 56 [AC-KongZhi]vlan 56 2 退出 [AC-KongZhi-vlan56]quit 3 进入vlan三层口 配置IP地址 [AC-KongZhi]interface Vlan-interface 56 [AC-KongZhi-Vlan-interface56]ip address 192.168.56.55 24 4 在AC控制器与Host主机的接口上能通关vlan 5…

高等数学重难点突破:高阶导数的计算

写在最前 文章目录 写在最前方法一&#xff1a;找规律方法二&#xff1a;牛顿莱布尼茨公式方法三&#xff1a;泰勒公式方法四&#xff1a; 数学归纳法 本文重点讨论总结面对高阶导数&#xff0c;我们可以使用哪些方法(工具&#xff09;来解决计算高阶导数问题 方法概述&#xf…

【入门教程一】基于DE2-115的My First FPGA 工程

1.1. 概述 这是一个简单的练习&#xff0c; 可以帮助初学者开始了解如何使用Intel Quartus 软件进行 FPGA 开发。 在本章节中&#xff0c;您将学习如何编译 Verilog 代码&#xff0c;进行引脚分配&#xff0c;创建时序约束&#xff0c;然后对 FPGA 进行编程&#xff0c;驱动开…

【Redis】主从复制分析-基础

1 主从节点运行数据的存储 在主从复制中, 对于主节点, 从节点就是自身的一个客户端, 所以和普通的客户端一样, 会被组织为一个 client 的结构体。 typedef struct client {// 省略 } client;同时无论是从节点, 还是主节点, 在运行中的数据都存放在一个 redisServer 的结构体中…