C++参悟:正则表达式库regex(更新中)

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

一、概述

C++标准库为我们提供了处理字符串的正则表达式库。正则表达式是一种用于在字符串中匹配模式的微型语言。

正则表达式在查询、替换字符串的时候有很多快速的使用场景,是一个经常使用的工具。正则表达式需要使用到正则表达式的语法,这个语法是独立于编程语言外的一个工具。这个可以 在线查看和测试

菜鸟学习教程 :https://www.runoob.com/regexp/regexp-syntax.html
C++参悟:正则表达式库regex(更新中),▼ C/C++  参悟笔记,c++,正则表达式,开发语言,regex库

在线测试工具 :https://stackoverflow.org.cn/regex/
C++参悟:正则表达式库regex(更新中),▼ C/C++  参悟笔记,c++,正则表达式,开发语言,regex库

这个用到的头文件便是:

#include <regex>

二、快速上手Demo

1. 查找字符串

1. 采用迭代器查找

// 待匹配字符串
std::string s = "Some people, when confronted with a problem";

// 正则表达式匹配对象-匹配单词
std::regex word_regex("(\\w+)");

// 获取迭代器
auto words_begin = std::sregex_iterator(s.begin(), s.end(), word_regex);
auto words_end = std::sregex_iterator();

// 总元素个数
int count = std::distance(words_begin, words_end);

// 遍历元素
for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
		//  查询到的匹配对象
        std::smatch match = *i;

		// 输出这个匹配对象的内容
        std::string match_str = match.str();
		std::cout << "  " << match_str << '\n';
}

/* 输出结果
Some 
people
when 
confronted
with
a
problem
*/

2. 使用算法查找

// 待匹配字符串
std::string lines[] = {"Roses are #ff0000",
                           "violets are #0000ff",
                           "all of my base are belong to you"};
// 正则表达式对象
std::regex color_regex("#([a-f0-9]{2})"
                           "([a-f0-9]{2})"
                           "([a-f0-9]{2})");
// 匹配结果
std::vector<std::smatch> matchs;

// 简单匹配
for (const auto &line : lines) {
	std::smatch m;
	std::cout << line << ": " << std::boolalpha
		<< std::regex_search(line, m, color_regex) << "\n";
	matchs.push_back(m);
}
    
// 输出结果
for(auto m: matchs){
	if(m.ready() && !m.empty())
		std::cout << "Useful Color: " << m.str() << "\n";
}
/* 输出结果
Roses are #ff0000: true
violets are #0000ff: true
all of my base are belong to you: false
Useful Color: #ff0000
Useful Color: #0000ff
*/

2. 匹配字符串

有两个方法都可以去匹配字符串。可以用 regex_match 或者 regex_search

因为 regex_match 只考虑完全匹配,故同一 regex 可能在 regex_match 和 std::regex_search 间给出不同的匹配

// 构造正则表达式对象
std::regex re("Get|GetValue");
std::cmatch m;

// regex_search 方法
std::regex_search("GetValue", m, re);  // 返回 true ,且 m[0] 含 "Get"
std::regex_search("GetValues", m, re); // 返回 true ,且 m[0] 含 "Get"

// regex_match 方法
std::regex_match ("GetValue", m, re);  // 返回 true ,且 m[0] 含 "GetValue"
std::regex_match ("GetValues", m, re); // 返回 false

3. 替换字符串

#include <iostream>
#include <iterator>
#include <regex>
#include <string>
 
int main()
{
   std::string text = "Quick brown fox";
   std::regex vowel_re("a|e|i|o|u");
 
   // 写结果到输出迭代器
   std::regex_replace(std::ostreambuf_iterator<char>(std::cout),
                      text.begin(), text.end(), vowel_re, "*");
 	// 等价于下面的
 	// std::cout << '\n' << std::regex_replace(text, vowel_re, "*");
 
   // 构造保有结果的字符串
   std::cout << '\n' << std::regex_replace(text, vowel_re, "[$&]") << '\n';
}

// 输出
Q**ck br*wn f*x
Q[u][i]ck br[o]wn f[o]x

三、类关系梳理

1. 主类

这些类封装正则表达式和在字符的目标序列中匹配正则表达式的结果。

1. basic_regex

basic_regex :正则表达式对象

在源代码里面看到那个 std::regex 对象就是用这个 basic_regex 定义的

/** @brief Standard regular expressions. */
typedef basic_regex<char>    regex;

sub_match :标识子表达式所匹配的字符序列

match_results:标识一个正则表达式匹配,包含所有子表达式匹配

2. 算法

这些算法将封装于 regex 的正则表达式应用到字符的目标序列。

1. regex_match

regex_match:尝试匹配一个正则表达式到整个字符序列

2. regex_search

regex_search:尝试匹配一个正则表达式到字符序列的任何部分

使用 std::regex_search() 查找

//常用
template< class BidirIt,
          class Alloc, class CharT, class Traits >
bool regex_search( BidirIt first, BidirIt last,
                    std::match_results<BidirIt,Alloc>& m,
                    const std::basic_regex<CharT,Traits>& e,
                    std::regex_constants::match_flag_type flags = std::regex_constants::match_default ); 
//常用
template< class CharT, class Alloc, class Traits >
bool regex_search( const CharT* str,
                    std::match_results<const CharT*,Alloc>& m,
                    const std::basic_regex<CharT,Traits>& e,
                    std::regex_constants::match_flag_type flags = std::regex_constants::match_default ); 
//常用
template< class STraits, class SAlloc,
          class Alloc, class CharT, class Traits >
bool regex_search( const std::basic_string<CharT,STraits,SAlloc>& s,
                    std::match_results<
                    typename std::basic_string<CharT,STraits,SAlloc>::const_iterator, Alloc>& m,
                    const std::basic_regex<CharT, Traits>& e,
                    std::regex_constants::match_flag_type flags = std::regex_constants::match_default ); 

template< class BidirIt
          class CharT, class Traits >
bool regex_search( BidirIt first, BidirIt last,
                    const std::basic_regex<CharT,Traits>& e,
                    std::regex_constants::match_flag_type flags = std::regex_constants::match_default );

template< class CharT, class Traits >
bool regex_search( const CharT* str,
                    const std::basic_regex<CharT,Traits>& e,
                    std::regex_constants::match_flag_type flags = std::regex_constants::match_default ); 

template< class STraits, class SAlloc,
          class CharT, class Traits >
bool regex_search( const std::basic_string<CharT,STraits,SAlloc>& s,
                    const std::basic_regex<CharT,Traits>& e,
                    std::regex_constants::match_flag_type flags =std::regex_constants::match_default );

template< class STraits, class SAlloc,
          class Alloc, class CharT, class Traits >
bool regex_search( const std::basic_string<CharT,STraits,SAlloc>&&,
                    std::match_results<typename std::basic_string<CharT,STraits,SAlloc>::const_iterator, Alloc>&,
                    const std::basic_regex<CharT, Traits>&,
                    std::regex_constants::match_flag_type flags = std::regex_constants::match_default ) = delete; 

这个函数的部分参数说明

  • 待匹配字符串(三种输入)
    1. first, last - 标识目标字符序列的范围
    2. str - 指向空终止字符序列的指针
    3. s - 标识目标字符序列的指针
  • e - 应当应用到目标字符序列的 std::regex :其实就是正则匹配对象
  • m - 匹配结果 :用的是 match_results 对象描述
  • flags - 掌管搜索行为的 std::regex_constants::match_flag_type

3. regex_replace

regex_replace:以格式化的替换文本来替换正则表达式匹配的出现位置

3. 迭代器

regex_iterator:用于遍历在序列中找到的匹配正则表达式的整个集合。

regex_iterator :迭代一个字符序列中的所有正则表达式匹配

regex_token_iterator:迭代给定字符串中的所有正则表达式匹配中的指定子表达式,或迭代未匹配的子字符串

4. 异常

此类定义作为异常抛出以报告来自正则表达式库错误的类型。

regex_error :报告正则表达式库生成的错误信息

C++参悟:正则表达式库regex(更新中),▼ C/C++  参悟笔记,c++,正则表达式,开发语言,regex库

使用这个也是非常简单的

#include <regex>
#include <iostream>
 
int main()
{
    try {
        std::regex re("[a-b][a");
    }
    catch (const std::regex_error& e) {
        std::cout << "regex_error caught: " << e.what() << '\n';
        
        // 这个错误码定义在 6.常量.error_type 中
        if (e.code() == std::regex_constants::error_brack) {
            std::cout << "The code was error_brack\n";
        }
    }
}

// 输出
regex_error caught: The expression contained mismatched [ and ].
The code was error_brack

5. 特征

regex_traits 类用于封装 regex 的本地化方面。

regex_traits:提供正则表达式库所需的关于字符类型的元信息

6. 常量

定义于命名空间 std::regex_constants

1. syntax_option_type

syntax_option_type: 控制正则表达式行为的通用选项,这个参数是放在 regex 对象构造函数中去设置匹配的

就像这种

 std::regex re2(".*(a|xayy)", std::regex::extended);
constexpr syntax_option_type icase = /*unspecified*/;
 
constexpr syntax_option_type nosubs = /*unspecified*/;
constexpr syntax_option_type optimize = /*unspecified*/;
constexpr syntax_option_type collate = /*unspecified*/;
constexpr syntax_option_type ECMAScript = /*unspecified*/;
constexpr syntax_option_type basic = /*unspecified*/;
constexpr syntax_option_type extended = /*unspecified*/;
constexpr syntax_option_type awk = /*unspecified*/;
constexpr syntax_option_type grep = /*unspecified*/;
constexpr syntax_option_type egrep = /*unspecified*/;

解释

效果
icase 应当以不考虑大小写进行字符匹配。
nosubs 进行匹配时,将所有被标记的子表达式 (expr) 当做非标记的子表达式 (?:expr) 。不将匹配存储于提供的 std::regex_match 结构中,且 mark_count() 为零
optimize 指示正则表达式引擎进行更快的匹配,带有令构造变慢的潜在开销。例如这可能表示将非确定 FSA 转换为确定 FSA 。
collate 形如 “[a-b]” 的字符范围将对本地环境敏感。
multiline (C++17) 若选择 ECMAScript 引擎,则指定 ^ 应该匹配行首,而 $ 应该匹配行尾。
ECMAScript 使用改 ECMAScript 正则表达式文法
basic 使用基本 POSIX 正则表达式文法(文法文档)。
extended 使用扩展 POSIX 正则表达式文法(文法文档)。
awk 使用 POSIX 中 awk 工具所用的正则表达式文法(文法文档)。
grep 使用 POSIX 中 grep 工具所用的正则表达式文法。这等效于 basic 选项附带作为另一种分隔符的换行符 ‘\n’ 。
egrep 使用 POSIX 中 grep 工具带 -E 选项所用的正则表达式文法。这等效于 extended 附带 ’

ECMAScript, basic, extended, awk, grep, egrep 必须选取至多一个文法选项。若不选取文法选项,则设定为选取 ECMAScript 。其他选项作为修饰符工作,从而 std::regex(“meow”, std::regex::icase) 等价于 std::regex(“meow”, std::regex::ECMAScript|std::regex::icase)

注意
因为 POSIX 使用“最左最长”匹配规则(最长的匹配子序列得到匹配,且若存在数个这种子序列,则匹配最左者),故它不适用的例子之一是剖析标签语言:如 “<tag[^>]>.” 这种 POSIX 正则表达式会匹配从首个 “<tag” 到最末 “” 的任何内容,包含中间的每个 “” 和 “” 。另一方面, ECMAScript 支持非贪心匹配,且 ECMAScript 正则表达式 “<tag[^>]>.?” 会只匹配到首个闭标签。

下面描述 ECMA 和 POSIX 匹配的区别

#include <iostream>
#include <string>
#include <regex>
 
int main()
{
    std::string str = "zzxayyzz";
    std::regex re1(".*(a|xayy)"); // ECMA
    std::regex re2(".*(a|xayy)", std::regex::extended); // POSIX
 
    std::cout << "Searching for .*(a|xayy) in zzxayyzz:\n";
    std::smatch m;
    std::regex_search(str, m, re1);
    std::cout << " ECMA (depth first search) match: " << m[0] << '\n';
    std::regex_search(str, m, re2);
    std::cout << " POSIX (leftmost longest)  match: " << m[0] << '\n';
}

// 输出
Searching for .*(a|xayy) in zzxayyzz:
ECMA (depth first search) match: zzxa
POSIX (leftmost longest)  match: zzxayy

2. match_flag_type

match_flag_type:特定于匹配的选项,这个是用在 regex_match、regex_search、regex_replace 三个算法函数中的一个参数。

就像下面的 regex_match 函数的 flags 是给的默认值

template< class BidirIt,
          class CharT, class Traits >
bool regex_match( BidirIt first, BidirIt last,
                   const std::basic_regex<CharT,Traits>& e,
                   std::regex_constants::match_flag_type flags =
                      std::regex_constants::match_default );
constexpr match_flag_type match_default = {};
 
constexpr match_flag_type match_not_bol = /*unspecified*/;
constexpr match_flag_type match_not_eol = /*unspecified*/;
constexpr match_flag_type match_not_bow = /*unspecified*/;
constexpr match_flag_type match_not_eow = /*unspecified*/;
constexpr match_flag_type match_any = /*unspecified*/;
constexpr match_flag_type match_not_null = /*unspecified*/;
constexpr match_flag_type match_continuous = /*unspecified*/;
constexpr match_flag_type match_prev_avail = /*unspecified*/;
constexpr match_flag_type format_default = {};
constexpr match_flag_type format_sed = /*unspecified*/;
constexpr match_flag_type format_no_copy = /*unspecified*/;

注意: [first, last) 指代要匹配的字符序列。

常量 解释
match_not_bol [first,last) 中的首个字符将被处理成如同它不在行首(即 ^ 将不匹配 [first,first) )
match_not_eol [first,last) 中的最末字符将被处理成如同它不在行尾(即 $ 将不匹配 [last,last) )
match_not_bow “\b” 将不匹配 [first,first)
match_not_eow “\b” 将不匹配 [last,last)
match_any 若多于一个匹配可行,则任何匹配都是可接受的结果
match_not_null 不匹配空字符序列
match_continuous 仅匹配始于 first 的子串
match_prev_avail –first 是合法的迭代位置。设置时导致 match_not_bol 和 match_not_bow 被忽略
format_default 使用 ECMAScript 规则于 std::regex_replace 构造字符串(语法文档)
format_sed 于 std::regex_replace 使用 POSIX sed 工具规则。(语法文档)
format_no_copy 不复制不匹配的字符串到 std::regex_replace 中的输出
format_first_only 仅替换 std::regex_replace 中的首个匹配

match_defaultformat_default 以外的所有常量都是位掩码元素。 match_defaultformat_default 常量是空位掩码。

3. error_type

error_type:描述不同类型的匹配错误,可以用 try catch 捕获

constexpr error_type error_collate = /*unspecified*/;
constexpr error_type error_ctype = /*unspecified*/;
constexpr error_type error_escape = /*unspecified*/;
constexpr error_type error_backref = /*unspecified*/;
constexpr error_type error_brack = /*unspecified*/;
constexpr error_type error_paren = /*unspecified*/;
constexpr error_type error_brace = /*unspecified*/;
constexpr error_type error_badbrace = /*unspecified*/;
constexpr error_type error_range = /*unspecified*/;
constexpr error_type error_space = /*unspecified*/;
constexpr error_type error_badrepeat = /*unspecified*/;
constexpr error_type error_complexity = /*unspecified*/;
constexpr error_type error_stack = /*unspecified*/;

名词解释如下:文章来源地址https://www.toymoban.com/news/detail-812024.html

常量 解释
error_collate 表达式含有非法对照字符名
error_ctype 表达式含有非法字符类名
error_escape 表达式含有非法转义字符或尾随转义
error_backref 表达式含有非法回溯引用
error_brack 表达式含有不匹配的方括号对( ‘[’ 与 ‘]’ )
error_paren 表达式含有不匹配的括号对( ‘(’ 与 ‘)’ )
error_brace 表达式含有不匹配的花括号对( ‘{’ 与 ‘}’ )
error_badbrace 表达式在 {} 表达式中含有非法范围
error_range 表达式含有非法字符范围(例如 [b-a] )
error_space 没有将表达式转换成有限状态机的足够内存
error_badrepeat *?+{ 之一不后继一个合法正则表达式
error_complexity 尝试的匹配的复杂度超过了预定义的等级
error_stack 没有进行匹配的足够内存

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

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

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

相关文章

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

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

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

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

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

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

    2023年04月20日
    浏览(90)
  • 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日
    浏览(37)
  • 老夫的正则表达式大成了,桀桀桀桀!!!【Python 正则表达式笔记】

    特殊字符 .^$?+*{}[]()| 为特殊字符,若想要使用字面值,必须使用 进行转义 字符类 [] [] 匹配包含在方括号中的任何字符。它也可以指定范围,例: [a-zA-Z0-9] 表示a到z,A到Z,0到9之间的任何一个字符 [u4e00-u9fa5] 匹配 Unicode 中文 [^x00-xff] 匹配双字节字符(包括中文) 在 [] 中

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

    regex函数 正则表达式C++  

    2024年02月07日
    浏览(32)
  • 正则表达式学习笔记

    字符 说明 将下一字符标记为特殊字符、文本、反向引用或八进制转义符。 例如:“n\\\"匹配字符串\\\"n”。“n\\\"匹配换行符。序列”\\\\“匹配”“,”(“匹配”(\\\"。 ^ 匹配输入字符串开始的位置。 如果设置了RegExp对象的Multiline属性,^还会与\\\"n\\\"或\\\"r\\\"之后的位置匹配。 $ 匹配输入

    2024年02月11日
    浏览(49)
  • 学习笔记-正则表达式

    https://www.runoob.com/regexp/regexp-tutorial.html 正则表达式re(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为\\\"元字符\\\"),可以用来描述和匹配字符串的特定模式。 个人理解,re是对字符序列进行建模,建立多对一映射,能够覆盖所有字符

    2024年02月09日
    浏览(48)
  • 正则表达式笔记

    /你的正则表达式写在这里/ 1?        1出现0次或1次 1*        1出现0次或多次 1+        1出现1次或多次 1{2}        1出现了2次 1{2,3}        1出现了2到3次 1{2,}        1出现了2次及以上 (5555){1}        5555出现了1次 (dog|cat)        dog或者cat [a-zA-Z]   

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

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

    2024年02月11日
    浏览(88)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包