正则表达式

正则表达式

1.什么是正则表达式?

正则表达式就是一系列规则,描述了一种字符串匹配的模式,通过这个规则可以在字符串中找到相关的内容;以下以c++语言使用正则表达式为例;

2.正则表达式使用大致流程

c++中正则表达式API基本在regex头文件中,使用正则表达式的大致流程:

  1. 你有一段需要处理的文本,字符串、文本文件、日志等
  2. 有一个特定目标,找出文本文件中所有的时间和日期等
  3. 根据可能的格式写出具体的正则表达式,比如日期是2020-01-01,正则表达式可能是这样:\d{4}-\d{2}-\d{2}。
  4. 将文本和正则表达式交给正则表达式引擎(由具体的语言提供),引擎会在文本中搜索到匹配的结果;

3.三种最常见的使用方式

  1. 匹配:判断给的字符串是否符合某个正则表达式,比如判断当前文本是否全部由数字组成:
    在这里插入图片描述
  2. 搜索:在一大段文本中搜索匹配的目标:
    在这里插入图片描述
  3. 替换
    在这里插入图片描述

4.正则表达式语法

  1. c++中内置了多种正则表达式语法,在创建的时候可以通过参数来选择;我们直接使用默认选项ECMAScript语法,也就是ECMA-262(JavaScript中也是使用它);详情可以点击链接:http://ecma-international.org/ecma-262/5.1/#sec-15.10

  2. 如果正则表达式有太多的转义字符,变得很复杂的时候,可以使用Raw string literal,原始字符串,他不会将反斜杠解释为转义字符;比如:
    string s = R"(\w\w\\w)";

  3. 字符类:对字符的分类,比如0~9属于数字字符;

       字符类           简写                   说明
     [[:alnum:]]                            字母和数字
     [_[:alnum:]]       \w              字母,数字以及下划线 
     [^_[:alnum:]]      \W             非字母,数字以及下划线
     [[:digit:]]        \d                     数字
     [^[:digit:]]       \D                    非数字
     [[:space:]]        \s                   空白字符 
     [^[:space:]]       \S                  非空白字符
     [[:lower:]]                             小写字母
     [[:upper:]]                             大写字母
     [[:alpha:]]                             任意字母
     [[:blank:]]                         非换行符的空白字符
     [[:cntrl:]]                             控制字符
     [[:graph:]]                             图形字符
     [[:print:]]                            可打印字符
     [[:punct:]]                             标点字符
     [[:xdigit:]]                         十六进制的数字字符
    

说明:
①字符类通过[]来标识,使用方括号包含一系列字符能够匹配其中任意一个字符,比如[abc]就是匹配a或b或c。
所以这两个字符在正则表达式中是特殊字符,如果想使用这两个字符,需要转义;相同的还有\r、\n、\t、\\、^、\.、\$等
②在[]内部,^标识否定;
③一些常用的字符类拥有简写
请添加图片描述
请添加图片描述
输出结果为:
请添加图片描述
4. 重复:一次性匹配一个完整的字符串,例如一个电话号码

          	字符                  	说明
			{n}						重复n次
			{n,}					重复n或更多次
			{n,m}                   重复n~m次
			*						等同于{0,}
			+						等同于{1,}
			?						等同于{0,1}

请添加图片描述
输出结果为:
请添加图片描述

5.正则表达式编程

  1. 迭代器:统计出文档中单词的数量
    请添加图片描述

  2. 正则表达式选项
    在创建正则表达式时,除了描述规则本身之外的字符串之外,还可以传递一个flag_type类型的参数,定义在std::regex_constants::syntax_option_type中;flag_type类型有以下值:

    		 值                        效果
    		icase           以不考虑大小写进行字符匹配。
    		nosubs        进行匹配时,将所有被标记的子表达式 
    					  (expr) 当做非标记的子表达式 (?:expr) 。
    					  不将匹配存储于提供的 std::regex_match 
    					  结构中,且 mark_count() 为零
    		optimize      指示正则表达式引擎进行更快的匹配,带有
    					  令构造变慢的潜在开销。例如这可能表示将
    					  非确定 FSA 转换为确定 FSA 。
    	    collate       形如 “[a-b]” 的字符范围将对本地环境敏感。
      multiline(C++17)  若选择 ECMAScript 引擎,则指定^匹配行
                          首,$应该匹配行尾。
    

这其中最常用的就是icase,比如要匹配文本中所有的"hahaha",并不区分大小写,就可以这样构建正则表达式:

	regex word_regex("hahaha?",regex::icase);
  1. 匹配结果与分组

当我们使用正则表达式时,有时需要捕获匹配结果的子串,比如我们匹配了日期之后还希望拿到年份、月份等信息;

std::match_results用来存储匹配结果,分组(c++中分组叫做子匹配:std::sub_match)用来捕获子串,圆括号()就是用来分组的;当在正则表达式中配对的使用圆括号时就会形成一个分组,分组通过编号0,1,2…来区分,编号0是匹配的整体,其他的根据分组顺序确定;

这些分组最终可以在匹配完成之后通过std::match_results的API来获取:

      API                    说明
	empty              检查匹配是否成功
	size			   返回结果的匹配数	
	max_size		 返回子匹配的最大可能数
	length 			  返回特定分组的长度
	position		返回特定分组首字符的位置
	str		         返回特定分组的字符串
	operation[]		    返回指定的分组
	prefix		  返回目标序列起始和完整匹配起始之间的分组
	suffix		  返回完整匹配结果和目标序列结尾之间的分组

示例:查找出文本文件中的所有年代,并分离出世纪部分和年份部分:
请添加图片描述
请添加图片描述
在实际应用中,常常会写出非常复杂的正则表达式,可以点这里查看一些实例: http://regexlib.com/DisplayPatterns.aspx

复杂的正则表达式常常很难理解,以下两个工具可以帮上忙:
https://regex101.com
https://www.debuggex.com

深入学习可以看书《精通正则表达式》

6说明

本文来自公众号c语言与cpp编程中的文章《c++与正则表达式》;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值