正则表达式(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

https://blog.csdn.net/asialee_bird/article/details/103420321#1%E3%80%81regex%E5%BA%93%E7%BB%84%E4%BB%B6%E4%BD%BF%E7%94%A8%E5%87%86%E5%A4%87


C++正则表达式入门

C++正则表达式的初步使用的更多相关文章

  1. Javascript正则表达式的初步学习

    <html> <head> <meta charset="utf-8"> <title>正则表达式的学习</title> ...

  2. re正则表达式讲解—初步认识

    # f = open(r"C:\Users\LENOVO\Desktop\模特.txt",'r') # 1.常规提取文档内容方法 # contacts = [] # for i i ...

  3. 如何使用JavaScript和正则表达式进行数据验证

    利用客户端JavaScript的优势,JavaScript中的正则表达式可以简化数据验证的工作,下面与大家分享下如何使用JavaScript和正则表达式进行数据验证,感兴趣的朋友可以参考下哈 数据验证 ...

  4. 邮箱/邮件地址的正则表达式及分析(JavaScript,email,regex)

    简言 在做用户注册时,常会用到邮箱/邮件地址的正则表达式.本文列举了几种方案,大家可以根据自己的项目情况,选择最适合的方案. 方案1 (常用) 规则定义如下: 以大写字母[A-Z].小写字母[a-z] ...

  5. [java] 汇率换算器实现-插曲1-正则表达式(1)

    [java] 汇率换算器实现-插曲1-正则表达式(1) // */ // ]]> // */ // ]]>   [java] 汇率换算器实现-插曲1-正则表达式(1) Table of C ...

  6. .NET身份证验证

    身份证号码编码规则及校验位校验算法 算法地址:http://jingyan.baidu.com/article/7f41ececff944a593d095c8c.html 简单验证长度 /// < ...

  7. 《mysql必知必会》笔记1(检索、排序、过滤、计算、汇聚、分组)

    一:了解SQL 1:列是表中的字段,所有表都由一个或多个列组成的.行是表中的记录,表中的数据都按行存储. 2:表中每一行都应该有可以唯一标识自己的一列或一组列.主键(一列或一组列),其值能够唯一区分每 ...

  8. Python——正则表达式初步应用(一)

    1.先附上转载(www.cnblogs.com/huxi)的一张图,有重要的参考价值,其含义大家请通过阅读来理解. 2.附上初步学习Python时编写的一个爬糗事百科段子的代码. # -*- codi ...

  9. 第5天(半天)【shell编程初步、grep及正则表达式】

    第5天(半天)[shell编程初步.grep及正则表达式] shell编程初步(01)_recv shell脚本:文本文件 #!:/bin/bash #!:/usr/bin/python #!:/us ...

  10. C#抓取数据、正则表达式+线程池初步运用

    去年底用 多线程+HtmlAgilityPack.dll 写了一个抓取“慧聪网” 公司信息的小程序,代码惨不忍赌.好在能抓到数据,速度也能让人忍受就很久没管了. 最近这段时间把这个小程序发给同事看着玩 ...

随机推荐

  1. 【Javaweb】六-servlet层

    AdminServlet.jap @WebServlet("/AdminServlet") public class AdminServlet extends HttpServle ...

  2. Android OpenGL ES入门

    1.OpenGL 和OpenGL ES OpenGL(Open Graphics Library)是一种用于渲染2D和3D图形的跨平台编程接口.OpenGL提供了一套标准的函数和接口,使开发人员能够在 ...

  3. 从根上理解elasticsearch(lucene)查询原理(1)-lucece查询逻辑介绍

    大家好,我是蓝胖子,最近在做一些elasticsearch 慢查询优化的事情,通常用分析elasticsearch 慢查询的时候可以通过profile api 去分析,分析结果显示的底层lucene在 ...

  4. lua完整学习笔记

    lua注释 -- 单行注释 --[[ 多行注释 ]]-- lua数据结构 nil          无效值与Java的Null类似,但是在条件表示中是false boolean      布尔值,tu ...

  5. 文心一言 VS 讯飞星火 VS chatgpt (153)-- 算法导论12.2 9题

    九.用go语言,设 T 是一棵二叉搜索树,其关键字互不相同;设 x 是一个叶结点,y 为其父结点.证明: y.key 或者是 T 树中大于 x.key 的最小关键字,或者是 T 树中小于 x.key ...

  6. skywalking插件工作原理剖析

    1. 官方插件二次开发 前面在介绍skywalking-agent目录时,提到了它有一个插件目录,并支持动态的开发插件.其实skywalking默认已经提供大部分框架的插件了,一般情况下不需要额外开发 ...

  7. K8s 里如何优雅地使用 /dev/shm 实现容器间共享内存

    目录 1. 从 docker run 的 --shm-size 参数聊起 2. Linux 里的 /dev/shm 3. Docker 对共享内存的支持 4. K8s 里如何设置 /dev/shm 大 ...

  8. 针对el-menu-item组件的警告Invalid event arguments: event validation failed for event "cli

    现象: 解决办法: 加上index这个唯一标识,不然会有意想不到的问题

  9. MySQL日期时间加|减法

    日期加法 select date_add(curdate(), interval N SECOND); -- 加N秒 select date_add(curdate(), interval N MIN ...

  10. Pix4Dmapper空间三维模型的应用实例:GIS选址分析

      本文介绍基于无人机影像建模完成后的结果,利用ArcMap软件进行空间选址分析,从而实现空间三维模型应用的方法. 目录 1 空间分析目标确立 2 基于基本约束条件的选址求解 2.1 坡度计算与提取 ...