【C++】标准库 — 正则表达式 std::regex

这篇具有很好参考价值的文章主要介绍了【C++】标准库 — 正则表达式 std::regex。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C++ 标准库 — 正则表达式 std::regex

I - 正则表达式概述


从 C++11 起,标准库增加了正则表达式 (Regular Expression) — std::regex ,包含在头文件 <regex> 中。
描述字符序列的方法,用于字符(串)的模式/模糊匹配。

用途 ,一般只有两种用途:

  1. 查找 (是否包含,找出来)
std::regex_match(seq, r, mft); // (seq, m, r, mft)
std::regex_search(seq, r, mft); // (seq, m, r, mft)
标识 释义
seq sequence 表示目标序列
r regex 表示模式,即正则表达式
m match 对象,即 std::match_results 匹配到结果数组
mft match flag type 匹配标识选项位掩码类型 (bitmask type)
  1. 替换(替换内容,替换格式)
std::regex_replace(seq, r, fmt, mft);
标识 释义
seq sequence 目标序列
r regex 表示模式,即正则表达式
fmt 正则表达式替换格式字符串,准确语法依赖于 flags 的值
mft match flag type 匹配标识选项位掩码类型 (bitmask type)

II - 内容


正则表达式各语言间通用,ECMAScript 规范,在不同语言间,有可能伴随很小的差异。主要包含三种内容:

    1. 匹配字符 \w\d\s
    1. 匹配数量 +*?{n}
    1. 内置字符特殊用途 ^$[]

2.1 - 匹配字符


基础字符

字符 说明
\w 匹配字符或数字或下划线
\W 匹配除了字符/数字/下划线以外的字符
\d 匹配数字
\D 匹配任意非数字的字符
\s 匹配任意空白符
\S 匹配任意非空白符的字符

字母大小写表示匹配相反的内容

空白符:比如换行符 ’ \n ', 制表符 ’ \t ’ 等, 空白符表


空白符 描述
’ ’ space (SPC)
‘\t’ horizontal tab (TAB)
‘\n’ newline (LF) line feed
‘\v’ vertical tab (VT)
‘\f’ form feed (FF)
‘\r’ carriage return (CR)

比如有些地方看到的 CRLF 就是说 Windows 的换行符 \r\n , Carriage Return Line Feed
LF 即 Linux 的换行符 \n , Line Feed

内置通用字符簇

字符簇 说明
[[:alpha:]] 任何字母
[[:digit:]] 任何数字
[[:alnum:]] 任何字母和数字
[[:xdigit:]] 任何 16 进制字符,相当于 [0-9a-fA-F] (中括号稍后解释)
[[:space:]] 任何空白符
[[:upper:]] 任何大写字母
[[:lower:]] 任何小写字母
[[:punct:]] 任何标点符号

注意:alpha 不为希腊字母 α 。
alpha = alphabet 字母表,26 个字母,也就是全部的字母
alnum = alphanumeric 含有数字和字母的,有些库提供接口如

isAlphanumeric() // 表示字符串或序列是否由数字和字母组成

punct = punctuation 标点

2.2 - 匹配数量/次数


字符 说明
+ 一次或多次,即 >= 1 次
* 零次或多次,即 >= 0 次
零次或一次,是或否
{n} 确定的 n 次
{n, m} n 到 m 次,如果 { n, } 则表示大于等于 n 次,也就是从 n 到无限大,m 为无限大

2.3 - 特殊字符的用途


字符 说明
. 匹配任何除了 换行或行终止符 (line terminators LF, CR, LS, PS) 之外的任何单个字符
^ 匹配字符串开始的位置
$ 匹配字符串结尾的位置
[] 匹配范围,例:[a-z] 小写字母
[^] 匹配反向范围,例:[^a-z] 所有小写字母意外的字符
| 两个匹配条件进行逻辑或运算
() 匹配子表达式 例 (him|her) 匹配 him 或 her

LS (line separator):行分隔符,Unicode 字符 2028
PS (paragraph separator):段落分隔符,Unicode 字符 2029
此两者均为不可见字符。

示例:匹配一个 C++ 源文件

std::regex r("[[:alnum:]]+\\.(cpp|cxx|cc)$");

通常一个 C++ 的源文件,形式为 字母数字加 . 加后缀名 cpp/cxx/cc 结尾。$ 即是表示字符串结尾。由于 . 有特殊用途所以表示一个点字符则需要加上 \,而反斜杠在 C++ 中为转义字符,所以表示一个反斜杠需要使用双反斜杠 \\ ,因此正则表达式表示匹配一个点字符为:\\.

III - 使用

3.1 - 正则表达式有不止一种写法


[0-9] 代表的含意与 \d 就是完全等价的,表示一个数字字符
再者如 [a-z0-9A-Z_] 也完全等同于 \w 表示一个字母/数字/下划线字符。

3.2 - 内置通用字符簇特殊用法


内置通用字符簇可以添加字符,也可以反向匹配,如:

[^[:digit:]] 等价于 \D ,所有非数字字符
[^[:space:]] 等价于 \S ,所有非空白符
[_[:alnum:]] 等价于 \w ,字母/数字/下划线字符
[^_[:alnum:]] 等价于 \W , 所有非字母/数字/下划线字符

3.3 - 元字符使用


\b 并不匹配字符,而是匹配字符位置,与 ^$ 类似。

例如匹配字符两端加上 \b 即可做到整词匹配 (whole word),如 \bword\b 只会匹配到 word,而不会匹配到如 sword 或 words 等。

示例:匹配一个 IP 地址

std::regex ip("\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b");

首尾的 \\b 表示整词匹配,\\. 表示匹配 IP 地址中的点符号, () 表示一个子表达式。
子表达式中分三部分,

  • 第一部分 - 可以为 250 到 255
  • 第二部分 - 200 到 249
  • 第三部分 - ? 表示存在或不存在, [01]? 表示百位的 0 或 1 或者不存在,有时写 IP 时可不写为 0 的高位数 如 247.231.3.19 。 后置的 [0-9]? 可与前面的 [0-9] 结合表示两位数字,或者不存在,使用前者表示单个数字。

3.4 - 零宽断言


(Lookahead and Lookbehind Zero-Length Assertions)

用于查找在某些内容 (但并不包括这些内容) 之前或之后的内容,也就是说它们像 \b , ^ , $ 那样用于指定一个位置,这个位置应该满足一定的条件 (即断言) ,因此它们也被称为零宽断言。

(?=exp) 称为零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式 exp。比如 \b\w+(?=s\b),匹配以 s 结尾的单词前面的部分(除了 s 以外的部分),如查找句子 There are some books, some fruits and some cups。时,它会匹配 book, fruit 和 cup。

(?<=exp) 称为零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式 exp 。如 (?<=\bre)\w+\b 会匹配以 re 开头的单词后面的部分 (除了 re 以外的部分),例如在查找 redo an action 时,它匹配 do 。

以下两种为确保不存在的断言,类似于前面讲到的反向匹配,可结合 [a-z][^a-z] 来理解。

(?!exp) 称为零宽度负预测先行断言,断言此位置的后面不能匹配表达式 exp 。例如:\d{3}(?!\d) 匹配三位数字,而且这三位数字的后面不能是数字;\b((?!abc)\w)+\b 匹配不包含连续字符串abc的单词。

(?<!exp) 称为零宽度负回顾后发断言,用来断言此位置的前面不能匹配表达式 exp(?<![a-z])\d{7} 匹配前面不是小写字母的七位数字。

速记:

符号 内容
?= 正预测
?<= 正回顾
?! 负预测
?<! 负回顾

= 表示相同,即匹配, ! 表示取反,即反向匹配,无 < 为预测,有 < 为回顾

3.5 - 宽字符匹配


正则表达式提供一套宽字符类型的操作

std::wregex;
std::wregex_iterator;

3.6 - 代码示例


格式转换示例

string phone = "(\\()?(\\d{3})(\\)?)([-. ])?(\\d{3})([-. ])?(\\d{4})";
regex r(phone);
smatch m;
string s = "morgan (609) 555-0132 201.555.0175 800.555.0000";
string fmt = "$2.$5.$7";// 将号码格式改为 ddd.ddd.dddd
cout << regex_replace(s, r, fmt) << endl;
cout << regex_replace(s, r, fmt, regex_constants::format_no_copy) << endl;

输出

morgan 609.555.0132 201.555.0175 800.555.0000
609.555.0132 201.555.0175 800.555.0000
  • 代码中正则表达式表示 7 个子表达式
"(\\()?(\\d{3})(\\)?)([-. ])?(\\d{3})([-. ])?(\\d{4})"
  1. (\\()? 左括号,是否存在
  2. (\\d{3}) 三位数字
  3. (\\)?) 右括号,是否存在
  4. ([-. ])? 减符号,点符号,空格,以及子表达式是否存在
  5. (\\d{3}) 三位数字
  6. ([-. ])? 减符号,点符号,空格,以及子表达式是否存在,同表达式 4
  7. (\\d{4}) 四位数字
  • 其中代码中变量 fmt 值中的 $2.$5.$7 分别代表第 2 个表达式,第 5 个表达式,第 7 个表达式,中间使用点符号分开。
    第 0 个表达式为全集,超过第 7 个表达式即为空。

  • regex_constants::format_no_copy 表示不输出序列中未匹配的部分

3.7 - 注意事项


正则表达式不为 C++ 的一部分,所以无法做到编译时检查,可能会出现运行时构造错误,不符合正则表达式语法的情况。

在大型项目中使用正则表达式时,可以先写一个小程序的 demo ,用于检测正则表达式是否语法正确,避免大型程序需要较长的运行时间才会构建正则表达式对象,在遇到不符合语法导致抛出异常,反复修改至正常运行,从而浪费了较多时间。

示例代码

try {
	regex r("[[:alnum:]+\\.(cpp|cxx|cc)$", regex::icase);
} catch (regex_error & e) {
	cout << e.what() << "\ncode:" << e.code() << endl;
}

此种情况下会输出

regex_error(error_brack):
The expression contained mismatched [ and ].
code: 4

代码中 regex::icase 表示忽略字母大小写


IV - 参考链接

  • 正则表达式30分钟入门教程
    http://help.locoy.com/Document/Learn_Regex_For_30_Minutes.htm

  • cppreference
    https://en.cppreference.com/w/cpp/regex

  • Regular-Expressions.info
    https://www.regular-expressions.info/
    https://www.regular-expressions.info/lookaround.html文章来源地址https://www.toymoban.com/news/detail-509574.html

到了这里,关于【C++】标准库 — 正则表达式 std::regex的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C# 正则表达式(Regex类)

    正则表达式是由普通字符(如英文字母)以及特殊字符(也称为元字符)组成的一种文字模式 这种文字模式可用于检查字符串的值是否满足一定的规则,例如: 验证输入的邮箱是否合法 输入的身份证号码是否合法 输入的用户名是否满足条件等 也可以进行字符串的替换和提

    2023年04月22日
    浏览(30)
  • C#Regex正则表达式(Regular Expression)

    在C#中,Regex是正则表达式(Regular Expression)的缩写,它是一种强大的文本匹配和处理工具。正则表达式是一种用于描述模式的字符串,它可以用来在文本中查找、替换和提取满足特定模式的内容。 在C#中,你可以使用System.Text.RegularExpressions命名空间下的Regex类来操作正则表达

    2024年02月05日
    浏览(31)
  • 身份证号码的正则表达式及验证详解(JavaScript,Regex)

    简言 在做用户实名验证时,常会用到身份证号码的正则表达式及校验方案。本文列举了两种验证方案,大家可以根据自己的项目实际情况,选择适合的方案 身份证号码说明 居民身份证号码,正确、正式的称谓应该是“公民身份号码”。根据【中华人民共和国国家标准 GB 11

    2023年04月20日
    浏览(29)
  • ABAP SQL & CDSView Entity中使用正则RegEx表达式(Regular Expressions)

    DEMO_REGEX DEMO_REGEX_TOY SQL函数 语法 作用 执行逻辑 返回类型 CDS   View Entities ABAP   SQL LIKE_REGEXPR LIKE_REGEXPR(            PCRE = pcre,            VALUE = sql_exp1[,            CASE_SENSITIVE = case]) 检查字符串是否包含任何 PCRE命中 检查sql_exp是否包含任何   PCRE命中,是则返

    2024年01月24日
    浏览(30)
  • 【JavaScript_2】语法、标准库、正则表达式

    1、强制转换 使用Number函数,可以将任意类型的值转化成数值。 Number函数将字符串转为数值,要比parseInt函数严格很多。基本上,只要有一个字符无法转成数值,整个字符串就会被转为NaN。 上面代码中,parseInt逐个解析字符,而Number函数整体转换字符串的类型。 另外,parseI

    2024年02月13日
    浏览(46)
  • 正则表达式C++

    regex函数 正则表达式C++  

    2024年02月07日
    浏览(25)
  • 小程序js(正则表达式):文本框对手机号进行标准化规范

      /^1[3456789]d{9}$/ 是一个正则表达式,用于匹配手机号码的格式。 具体解释如下: /  是正则表达式的开始和结束标记。 ^  表示匹配字符串的开头。 1  表示要匹配的字符串必须以数字 1 开头。 [3456789]  表示下一位的数字必须是 3、4、5、6、7、8 或 9 中的一个。 d  表示匹配

    2024年02月05日
    浏览(38)
  • 【编译原理】【词法分析】【正则表达式】【NFA】【DFA】【C++】正则表达式转DFA&NFA,判断字符串是否符合正则表达式的匹配算法

    显然,正则表达式、NFA、DFA的概念都很简单,所以直接上代码,注释应该解释地比较清楚, 没有万能头文件的自行替换需求库 ,如果有疑问的可以留言。 网盘链接 [自行补全]/s/1pbGT_wpB662TwFrnukXgGQ?pwd=TSIT 提取码:TSIT 原理可以参考这篇博客 传送门 本次程序由四个文件组成 文

    2024年02月11日
    浏览(73)
  • C++右值引用(左值表达式、右值表达式)(移动语义、完美转发(右值引用+std::forward))(有问题悬而未决)

    在 C++ 中,表达式可以分为左值表达式和右值表达式。左值表达式指的是可以出现在赋值语句左边的表达式,例如变量、数组元素、结构体成员等;右值表达式指的是不能出现在赋值语句左边的表达式,例如常量、临时对象、函数返回值等。 右值是指将要被销毁的临时对象或

    2024年02月04日
    浏览(33)
  • 【动态规划】【字符串】C++算法:正则表达式匹配

    视频算法专题 动态规划汇总 字符串 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘ ’ 的正则表达式匹配。 ‘.’ 匹配任意单个字符 \\\' ’ 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。 示例 1: 输入:

    2024年02月03日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包