C++正则表达式的初步使用
正则表达式(Regular Expressions),又被称为regex、regexp 或 RE,是一种十分简便、灵活的文本处理工具。它可以用来精确地找出某文本中匹配某种指定规则的内容。从C++11开始也将正则表达式纳入了新标准的一部分 。
本篇博客不涉及正则表达式语法的基本内容,如果你对正则表达式不了解,可以访问这个链接获得帮助。
C++11标准支持正则表达式后,使用正则表达式查找、提取、替换字符串就无需使用第三方开源库。
使用正则表达式包含头文件的 regex,其主要包含三个类(regex、smatch、ssub_match)和三个API(regex_search()、regex_match()、regex_replace()),基本可以满足使用的要求,其它都只是变种而已。

类regex,用来存放正则表达式,其实就是一个字符串,只需关心构造函数,其需要一个字符串作为参数进行对象构造。正则表达式语法遵循ECMAScript标准。
类smatch,用来存放查找、提取操作的结果,其实就是一个ssub_match的数组,正则表达式语法支持使用括号来获得某个子匹配,所以匹配结果会有多个,第一个存完整匹配结果,其它存正则表达式指定的子匹配。通过size()获取数组大小,操作符[]指定下标获取元素,也可以通过迭代器begin()、end()来遍历数组。prefix()和suffix()是获取查找结果前面和后面的字符串,比如“I am a good boy”查找am关键词,prefix()就是“I ”,suffix()就是“ a good boy”。
类ssub_match,用来存放某个匹配,其实就是一个字符串,其重载了操作符string(),所以可以当string对象来使用,length()返回匹配内容的长度,str()返回匹配的内容。
查找字符串使用regex_search() API,其有两个版本:
bool regex_search(string s, regex e);
bool regex_search(string s, smatch m, regex e);
第1个版本简单判断是否找到,指定搜索字符串和查找正则表达式
第2个版本除了判断是否找到外,还可以指定smatch对象获取查找结果。
匹配字符串使用regex_match() API,其跟regex_search()区别在于前者是完全匹配不能有冗余的字符,后者可以有冗余字符。比如字符串 subsentence,对于正则表达式sub来说,regex_match()是失败的,因为尾部sentence没有被匹配到,regex_search()是成功的。其函数原型与regex_search()一样。
替换字符串使用regex_replace() API
string regex_replace(string s, regex e, string fmt);
第一、二参数与regex_search一样,第三个参数要替换的内容,字符串里面支持使用$符号后面加数字,用来表示第几个子匹配的内容。
下面代码示例演示如何使用C++11的regex API,理解透该示例代码,你就基本掌握了其使用方法。
#include <string>
#include <regex>
#include <iostream>
//#include <bits/stdc++.h>
int main()
{
const std::string s = "this subject has a submarine as a subsequence";
const std::regex e("\\b(sub)([^ ]*)"); // sub开头的单词
// 只要查找是否有sub开头的单词
if (std::regex_search(s, e))
{
std::cout << "the source string contains word beginning by sub" << std::endl;
}
// 查找所有sub开头的单词,并打印出来
std::smatch m; //存放查找结果
std::string s2 = s;
while (std::regex_search(s2, m, e))
{
for (auto x : m) // 正则表达式有两个括号,m共有3个元素
{
std::cout << x << " ";
}
std::cout << std::endl;
s2 = m.suffix(); // 指向查找结果的下一个位置,继续查找
}
// 只要判断是否匹配
if (!std::regex_match(s, e)) // 要求完全匹配,这点跟查找不同
{
std::cout << "the source string is not match" << std::endl;
}
// 如果匹配,输出匹配结果
std::regex e2("(.*)sub(.*)"); // 含有关键词sub,并提取sub前和sub后的内容
if (std::regex_match(s, m, e2)) // 匹配成功了,m对象才是有效存放提取内容
{
for (unsigned i = 1; i < m.size(); i++) // 第1个元素就是s,这里就不打印
{
// 注意:因为正则表达式.*是尽可能的去匹配,所以关键词sub匹配的是
// 最后一个单词subsequence的sub
std::cout << m[i] << std::endl;
}
}
// 把subsequence替换成sub-sequence
std::regex e3("subsequence");
std::cout << std::regex_replace(s, e3, "sub-sequence") << std::endl;
// 把所有sub开头的单词,在sub后面加横线 -
// $2匹配结果smatch中第2个元素,也就是sub后面的内容
std::cout << std::regex_replace(s, e, "sub_$2") << std::endl;
}
参考
https://www.runoob.com/regexp/regexp-syntax.html
https://chenxiaowei.gitbook.io/c-17-stl-cook-book/chapter7-0-chinese/chapter7-12-chinese
C++正则表达式的初步使用的更多相关文章
- Javascript正则表达式的初步学习
<html> <head> <meta charset="utf-8"> <title>正则表达式的学习</title> ...
- re正则表达式讲解—初步认识
# f = open(r"C:\Users\LENOVO\Desktop\模特.txt",'r') # 1.常规提取文档内容方法 # contacts = [] # for i i ...
- 如何使用JavaScript和正则表达式进行数据验证
利用客户端JavaScript的优势,JavaScript中的正则表达式可以简化数据验证的工作,下面与大家分享下如何使用JavaScript和正则表达式进行数据验证,感兴趣的朋友可以参考下哈 数据验证 ...
- 邮箱/邮件地址的正则表达式及分析(JavaScript,email,regex)
简言 在做用户注册时,常会用到邮箱/邮件地址的正则表达式.本文列举了几种方案,大家可以根据自己的项目情况,选择最适合的方案. 方案1 (常用) 规则定义如下: 以大写字母[A-Z].小写字母[a-z] ...
- [java] 汇率换算器实现-插曲1-正则表达式(1)
[java] 汇率换算器实现-插曲1-正则表达式(1) // */ // ]]> // */ // ]]> [java] 汇率换算器实现-插曲1-正则表达式(1) Table of C ...
- .NET身份证验证
身份证号码编码规则及校验位校验算法 算法地址:http://jingyan.baidu.com/article/7f41ececff944a593d095c8c.html 简单验证长度 /// < ...
- 《mysql必知必会》笔记1(检索、排序、过滤、计算、汇聚、分组)
一:了解SQL 1:列是表中的字段,所有表都由一个或多个列组成的.行是表中的记录,表中的数据都按行存储. 2:表中每一行都应该有可以唯一标识自己的一列或一组列.主键(一列或一组列),其值能够唯一区分每 ...
- Python——正则表达式初步应用(一)
1.先附上转载(www.cnblogs.com/huxi)的一张图,有重要的参考价值,其含义大家请通过阅读来理解. 2.附上初步学习Python时编写的一个爬糗事百科段子的代码. # -*- codi ...
- 第5天(半天)【shell编程初步、grep及正则表达式】
第5天(半天)[shell编程初步.grep及正则表达式] shell编程初步(01)_recv shell脚本:文本文件 #!:/bin/bash #!:/usr/bin/python #!:/us ...
- C#抓取数据、正则表达式+线程池初步运用
去年底用 多线程+HtmlAgilityPack.dll 写了一个抓取“慧聪网” 公司信息的小程序,代码惨不忍赌.好在能抓到数据,速度也能让人忍受就很久没管了. 最近这段时间把这个小程序发给同事看着玩 ...
随机推荐
- 函数计算的新征程:使用 Laf 构建 AI 知识库
Laf 已成功上架 Sealos 模板市场,可通过 Laf 应用模板来一键部署! 这意味着 Laf 在私有化部署上的扩展性得到了极大的提升. Sealos 作为一个功能强大的云操作系统,能够秒级创建多 ...
- [编程]UML语言:理论之光与实践之惑
UML介绍及现状 UML(统一建模语言)是软件工程领域中具有悠久历史的一种模型化语言工具.它通过标准化的图形符号体系,使得软件系统的蓝图能够被更直观地表达出来.UML诞生于20世纪90年代,经过多年积 ...
- Vue04-vue-router
vue-router 目前前端流行的三大框架, 都有自己的路由实现: Angular:ngRouter React:ReactRouter Vue:vue-router Vue Router 是 Vu ...
- socket链接和发送demo
Socker 包是创建客户端的,用于链接服务器: ServerSocket 包是创建服务器的,启动端口进行监听等待链接 socket客户端-----------------java.lang.Stri ...
- Springboot的Container Images,docker加springboot
Spring Boot应用程序可以使用Dockerfiles容器化,或者使用Cloud Native Buildpacks来创建优化的docker兼容的容器映像,您可以在任何地方运行. 1. Effi ...
- [NOI online2022提高B] 讨论
题目描述 有 \(n\) 个人正在打模拟赛,模拟赛有 \(n\) 道题目. 有两人都会的题目并且没有人会的题目包含另一个人时,两者之间才会讨论. (定义第 ii 个人会的题目的集合为 \(S_i\) ...
- 【Dotnet 工具箱】推荐一个 Flutter 和 .NET 开源的实时聊天 APP
1. 推荐一个 Flutter 和 .NET 开源的实时聊天 APP Heyy-chat-app Heyy-chat-app 是一个开源的聊天应用,使用 Flutter.Asp.Net Core We ...
- keystone和beaengine的编译
编译Keystone 根据github的文档编译不出来,所以还是用CMake项目转成Visual Studio的项目来编译 1.下载源码 https://github.com/keystone-eng ...
- Python——Html(HEAD头部)
HTML中HEAD头部设置(了解) 在HTML中,<head> 元素是文档的头部部分,通常包含了一些关于文档的元信息和链接到外部资源的标签.以下是一些常见的 <head> 元素 ...
- 文心一言 VS 讯飞星火 VS chatgpt (19)-- go语言的slice和rust语言的Vec的扩容流程是什么?
go语言的slice和rust语言的Vec的扩容流程是什么? 文心一言: 在Go语言中,slice(切片)和Rust语言中的Vec都是用于存储一组固定长度的元素的数据结构.它们的扩容流程略有不同,下面 ...