正则表达式使用

正则表达式是文本搜索的一个利器,掌握它定会提高你的工作效率。

要使用正则表达式就必须知道有哪些元字符以及它们所代表的意义,这里我就不再对每个元字符做说明了,假设你已经了解了这些知识,如果还不了解可以参考网上的一些资料。

以下所有示例用的是一个在线的正则表达式测试工具来验证的,地址是 https://tool.oschina.net/regex/

比如11位的手机号:[0-9]{11},匹配结果如下图:

匹配指定数量字符

大括号里的数字表示重复前面匹配的数量,有以下几种写法

  1. {k} 表示重复次数k
  2. {m,} 表示重复次数不小于m
  3. {,n} 表示重复次数不大于n
  4. {m,n} 表示重复次数不小于m且不大于n

我用的这个测试工具不支持上面四种所有写法,只支持1,2,4这三种写法

比如匹配数字与字母相互交叉文本中的所有字母部分:[a-zA-Z]+,匹配结果如下图:

匹配至少1个字符(图1)

这种写法与[a-zA-Z]{1,}等效,得到同样结果,如下图所示:

匹配至少1个字符(图2)

还有一个可以表示匹配数量的元字符是*,不过它表示大于等于0个匹配,也就是说以下这种写法[a-zA-Z][a-zA-Z]* 也与 [a-zA-Z]+ 是等效的,得到同样结果,如下图所示:

匹配至少1个字符(图3)

这种匹配其实与前两种写法上没有多大区别,唯一的区别就是需要重复的文本不再是单个字符,而是其它正则表达式匹配的结果,比如匹配ip地址:([0-9]{1,3}\\.){3}[0-9]{1,3},匹配结果如下图:

通过\\n的方式可以引用第n个分组,比如查找不相邻的两个重复的单词:([a-zA-z]{5,}).+\\1,匹配结果如下图:

比如匹配开头是数字的文本:^[0-9]+,匹配结果如下图:

比如匹配结尾是数字的文本:[0-9]+$,匹配结果如下图:

比如搜索后面必须紧跟hello这个单词的数字:[0-9]+(?=hello),匹配结果如下图:

比如搜索后面一定不能紧跟hello这个单词的数字:[0-9]+(?!hello),匹配结果如下图:

比如搜索前面必须是数字的英文单词:(?<=[0-9]+)[a-zA-Z]+,匹配结果如下图:

比如搜索前面一定不是数字的英文单词:(?<![0-9]+)[a-zA-Z]+,匹配结果如下图:

C语言中使用正则表达式

POSIX 规定了正则表达式的C语言库函数, 参见regex(3), 我们已经学了很多C函数的用法 读者应该具备自己看懂man手册的能力

C语言中使用正则表达式一般分为三步:

1.编译正则表达式regcomp()

2.匹配正则表达式 regexec()

3.释放正则表达式 regfree()

先来通过一个demo展示一下这三个函数的用法

#include <cstdio>#include <sys/types.h>#include <regex.h> int main(int argc, char* argv[]){ if (argc != 3) { printf(\”Usage: %s RegexString AND Text\\n\”, argv[0]); return 1; } const char* p_regex_str = argv[1]; const char* p_txt = argv[2]; regex_t oregex; // 编译后的结构体 int ret = 0; char emsg[1024] = { 0 }; // 保存错误信息的数组 size_t emsg_len = 0; if ((ret = regcomp(&oregex, p_regex_str, REG_EXTENDED | REG_NOSUB)) == 0) {// 编译 //成功编译 if ((ret = regexec(&oregex, p_txt, 0, NULL, 0)) == 0) {// 执行匹配不保存匹配的返回值 printf(\”%s matches %s \\n\”, p_txt, p_regex_str); regfree(&oregex); return 0; } } emsg_len = regerror(ret, &oregex, emsg, sizeof(emsg)); // 如果出错得到错误信息 emsg_len = emsg_len < sizeof(emsg) ? emsg_len : sizeof(emsg) – 1; emsg[emsg_len] = \’\\0\’; printf(\”Regex error Msg : %s \\n\”, emsg); regfree(&oregex); return 1;}

效果:

下边是对这三个函数的详细解释

一. regcomp()这个函数把指定的正则表达式pattern编译成一种 特定的数据格式compiled, 这样使匹配更加有效

函数regexec()会使用这个数据在目标文件中匹配,执行成功返回0。

int regcomp(regex_t * compiled, const char* pattern, int cflags)

regex_t :是一个结构体类型,用来存储编译后的正则表达式,它的成员re_nsub用来存储正则表达式中的的正则表达式的个数

子正则表达式就是用括号括起来的那部分(在上一篇 我已经给大家事例过了)

pattern: 指向我们写好的正则表达式字符串的首地址

cflags: 这个参数有四个值:可以把它们用 “ | ” 连接起来

1.REG_EXTENDED :以功能更加强大的扩展正则进行匹配

2.REG_ICASE : 匹配字母是忽略大小写

3.REG_NOSUB: 不用存储匹配后的结果,只要返回是否成功匹配。如果设置该标记,那么 regexec()将忽略nmatch和

pmatch两个参数

4.REG_NEWLINE: 识别换行符 这样 “^”就可以从行的开头进行匹配 \”#34;就可以从行的结尾开始匹配

更多技术分享与交流点击关注,加入C/C++学习交流群:587250700和大家一起交流学习。

本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com

点赞 0
收藏 0

文章为作者独立观点不代本网立场,未经允许不得转载。