正则表达式(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. 关于Delphi

    # 关于Delphi ··Delphi中使用的面向对象pascal编程语言. ··Pascal语言最初由瑞士苏黎士理工学院的尼古拉斯-沃斯(Niklaus Wirth)教授在1971年设计. ··19 ...

  2. 手撕Vue-Router-实现router-link

    前言 在上一篇 [手撕Vue-Router-添加全局$router属性] 中,实现了将每一个 Vue 实例上挂载一个 $router 属性,这个属性就是我们在上一篇文章中创建的 VueRouter 实 ...

  3. Opencv学习笔记(1)

    1.安装环境 如何安装Python解释器和PyCharm,这里就不说明了, 参考文章链接:https://blog.csdn.net/weixin_72959097/article/details/1 ...

  4. 深度掌握TypeScript中的重载【函数重载、方法重载】

    深度掌握TypeScript中的重载[函数重载.方法重载] 1. 函数重载,方法重载的重要性 著名前端流行框架底层都用到函数重载,例如:Vue3 底层源码就多处使用到带泛型的函数重载.很多前端面试更是 ...

  5. 【scikit-learn基础】--『数据加载』之真实数据集

    上一篇介绍了scikit-learn中的几个玩具数据集,本篇介绍scikit-learn提供的一些真实的数据集.玩具数据集:scikit-learn 基础(01)--『数据加载』之玩具数据集 1. 获 ...

  6. uni-app全局样式和局部样式

    前言 好,经过上个章节的介绍完毕之后,了解了一下 UniApp 的一个全局 页面配置文件,也就是我们的一个 pages.json 文件. 那么了解完了这个文件之后,这片文章,再了解一下 UniApp ...

  7. 玩转Spring状态机

    说起Spring状态机,大家很容易联想到这个状态机和设计模式中状态模式的区别是啥呢?没错,Spring状态机就是状态模式的一种实现,在介绍Spring状态机之前,让我们来看看设计模式中的状态模式. 1 ...

  8. ElasticSearch之Clear cache API

    本方法用于清理缓存. 命令样例如下: curl -X POST "https://localhost:9200/testindex_001/_cache/clear?pretty" ...

  9. ElasticSearch之cat nodes API

    命令样例如下: curl -X GET "https://localhost:9200/_cat/nodes?v=true&pretty" --cacert $ES_HOM ...

  10. bash命令的使用

    bash的工作特性之命令执行状态返回值和命令展开所涉及的内容及其示例演出 !脚本执行与调试 1.绝对路径执行,要求文件有执行权限 2.以sh命令执行,不要求文件有执行权限 3..加空格或source命 ...