C语言用regcomp、regexec、regfree和regerror函数实现正则表达式校验
前言
首先,祝大家国庆假期玩的嗨皮!可能有的人已经在回家的路上了,是不是都看不到我的真挚祝福了?
C语言对于一些东西的封装比较少,比如正则表达式,但速度快一直使它立于不败之地,今天就要介绍如何用C封装。
一、正则表达式
1、介绍
应该都听过正则吧?主要应用在字符串匹配,而且它是通用的,各种语言都支持。例如可以用它匹配IP地址、邮箱等。举个例子说明一下正则有啥用:
例如,我在的公司,页面用PHP,后台用C,当添加用户邮箱时,我们老大就要求:PHP和C都要对用户输入的用户邮箱进行校验,这时正则表达式就派上用场了。
2、grep命令
我会用grep进行简单的举例,所以要简单介绍一下。
grep是一种查找过滤工具,正则表达式在grep中用来查找符合模式的字符串。其实正则表达式还有一个重要的应用是验证用户输入是否合法,例如用户通过网页表单提交自己的email地址,就需要用程序验证一下是不是合法的email地址,这个工作可以在网页的Javascript中做,也可以在网站后台的程序中做,例如PHP、Perl、Python、Ruby、Java或C,所有这些语言都支持正则表达式,可以说,目前不支持正则表达式的编程语言实在很少见。
egrep相当于grep -E,表示采用Extended正则表达式语法。
注意grep找的是包含某一模式的行,而不是完全匹配某一模式的行。
3、基本语法
对于正则表达式的语法,我只列出比较常见的,基本就够用了,如果有兴趣的可以再去网上学习,去深入了解。
字符类

数量限定符
位置限定符

举例:查找IP的正则
用^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$查找
其它特殊字符

4、分类
大致分为两类:Basic正则和Extended正则
区别:
以上介绍的是grep正则表达式的Extended规范,Basic规范也有这些语法,只是字符?+{}|()应解释为普通字符,要表示上述特殊含义则需要加\转义。如果用grep而不是egrep,并且不加-E参数,则应该遵照Basic规范来写正则表达式。
二、正则表达式相关函数
C语言处理正则表达式常用的函数有regcomp()、regexec()、regfree()和regerror()
C语言中使用正则表达式一般分为三步:
- 编译正则表达式 regcomp()
- 匹配正则表达式 regexec()
- 释放正则表达式 regfree()
下边将对三个函数的详细解释。
1、regcomp函数
功能:这个函数把指定的正则表达式pattern编译成一种特定的数据格式compiled,这样可以使匹配更有效。
原型:int regcomp(regex_t *preg, const char *regex, int cflags);
参数说明:
regex_t 是一个结构体数据类型,用来存放编译后的正则表达式,它的成员re_nsub 用来存储正则表达式中的子正则表达式的个数,子正则表达式就是用圆括号包起来的部分表达式。
参数regex: 是指向我们写好的正则表达式的指针。
参数cflags: 有如下4个值或者是它们或运算(|)后的值:
REG_EXTENDED 以功能更加强大的扩展正则表达式的方式进行匹配。
REG_ICASE 匹配字母时忽略大小写。
REG_NOSUB 不用存储匹配后的结果,只返回是否成功匹配。如果设置该标志位,那么在regexec(在下边介绍)将忽略nmatch和pmatch两个参数。
REG_NEWLINE 识别换行符,这样'$'就可以从行尾开始匹配,'^'就可以从行的开头开始匹配。
2、regexec函数
功能:函数regexec 会使用这个数据在目标文本串中进行模式匹配。
原型:int regexec(const regex_t *preg, const char *string, size_t nmatch,regmatch_t pmatch[], int eflags);
先来介绍下参数4中的regmatch_t结构体:
regmatch_t 是一个结构体数据类型,在regex.h中定义:
typedef struct {
regoff_t rm_so;
regoff_t rm_eo;
} regmatch_t;
成员rm_so 存放匹配文本串在目标串中的开始位置,rm_eo 存放结束位置。通常我们以数组的形式定义一组这样的结构。
参数说明:
preg 是已经用regcomp函数编译好的正则表达式。
string 是目标文本串。
nmatch 是regmatch_t结构体数组的长度。
matchptr regmatch_t类型的结构体数组,存放匹配文本串的位置信息。
eflags 有两个值:
REG_NOTBOL 让特殊字符^无作用
REG_NOTEOL 让特殊字符$无作用
3、regfree函数
功能:可以用这个函数清空regex_t结构体的内容
原型:void regfree(regex_t *preg);
4、regerror函数
功能:当执行regcomp 或者regexec 产生错误的时候,就可以调用这个函数而返回一个包含错误信息的字符串。
原型:size_t regerror(int errcode, const regex_t *preg, char *errbuf,size_t errbuf_size);
参数说明:
errcode 是由regcomp 和 regexec 函数返回的错误代号。
preg 是已经用regcomp函数编译好的正则表达式,这个值可以为NULL。
errbuf 指向用来存放错误信息的字符串的内存空间。
errbuf_size 指明buffer的长度,如果这个错误信息的长度大于这个值,则regerror 函数会自动截断超出的字符串,但他仍然会返回完整的字符串的长度。所以我们可以用如下的方法先得到错误字符串的长度。
三、程序示例
输入两个参数,第一个参数:正则表达式,第二个参数:字符串,校验是否匹配,程序如下:
#include <sys/types.h>
#include <regex.h>
#include <stdio.h> int main(int argc, char ** argv)
{
if (argc != ) {
printf("Usage: %s RegexString Text\n", argv[]);
return ;
}
const char * pregexstr = argv[];
const char * ptext = argv[];
regex_t oregex;
int nerrcode = ;
char szerrmsg[] = {};
size_t unerrmsglen = ;
if ((nerrcode = regcomp(&oregex, pregexstr, REG_EXTENDED|REG_NOSUB)) == ) {
if ((nerrcode = regexec(&oregex, ptext, , NULL, )) == ) {
printf("%s matches %s\n", ptext, pregexstr);
regfree(&oregex);
return ;
}
}
unerrmsglen = regerror(nerrcode, &oregex, szerrmsg, sizeof(szerrmsg));
unerrmsglen = unerrmsglen < sizeof(szerrmsg) ? unerrmsglen : sizeof(szerrmsg) - ;
szerrmsg[unerrmsglen] = '\0';
printf("ErrMsg: %s\n", szerrmsg);
regfree(&oregex); return ;
}
演示匹配邮箱:
执行:./a.out "^[a-zA-Z0-9]+@[a-zA-Z0-9]+.[a-zA-Z0-9]+" "ldw@itcast.com"
演示结果如下:

总结
希望喜欢的点关注,不迷路哦!会持续更新linux C/C++相关内容,谢谢支持!
C语言用regcomp、regexec、regfree和regerror函数实现正则表达式校验的更多相关文章
- C语言正则表达式详解 regcomp() regexec() regfree()详解
标准的C和C++都不支持正则表达式,但有一些函数库可以辅助C/C++程序员完成这一功能,其中最著名的当数Philip Hazel的Perl-Compatible Regular Expression库 ...
- [转]C语言文件输入/输出ACM改进版(freopen函数)
C语言文件输入/输出ACM改进版(freopen函数) 2009年5月27日 10:379,457 浏览数发表评论阅读评论 文章作者:姜南(Slyar) 文章来源:Slyar Home (www. ...
- 智能合约语言 Solidity 教程系列10 - 完全理解函数修改器
这是Solidity教程系列文章第10篇,带大家完全理解Solidity的函数修改器. Solidity系列完整的文章列表请查看分类-Solidity. 写在前面 Solidity 是以太坊智能合约编 ...
- PHP 语言结构(Language constructs)和函数的区别
相信大家经常看到对比一些PHP应用中,说用isset() 替换 strlen(),isset比strlen执行速度快等. 例子: if ( isset($username[5]) ) { // The ...
- regcomp/regexec/regfree--POSIX regex functions
语法 #include <sys/types.h> #include <regex.h> int regcomp(regex_t *preg, const char *rege ...
- C语言中的回调函数调用过程以及函数指针使用
回调函数比喻: 你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货. 在这个例子里,你的电话号码就叫回调 ...
- TCL语言笔记:TCL中的数学函数
一.TCL数学函数列表 函数名 说明 举例 abs(arg) 取绝对值 set a –10 ; #a=-10 set a [expr abs($a)]; # a=10 acos(arg) 反余弦 s ...
- c程序设计语言_习题1-16_自己编写getline()函数,接收整行字符串,并完整输出
Revise the main routine of the longest-line program so it will correctly print the length of arbitra ...
- c语言里用结构体和指针函数实现面向对象思想
一.基础研究 观察如下两个程序a.c和b.c: A.c: B.c: 这两个程序都是要实现在屏幕上第10行40列打印一个绿色的字符c: 这两个程序的数据组织方式是一样的,都是使用结构体,而且对共性和个性 ...
随机推荐
- sql server 2012 减少日志
USE [master] GO ALTER DATABASE 数据库名 SET RECOVERY SIMPLE WITH NO_WAIT GO ALTER DATABASE 数据库名 SET RECO ...
- Spark内部执行机制
Spark内部执行机制 1.1 内部执行流程 如下图1为分布式集群上spark应用程序的一般执行框架.主要由sparkcontext(spark上下文).cluster manager(资源管理器)和 ...
- docker pull 镜像报错
[root@localhost ~]# docker pull ningx Using default tag: latest Trying to pull repository docker.io/ ...
- MangoDb的安装及使用
安装步骤 一.创建文件 vi /etc/yum.repos.d/mongodb-org-3.6.repo 二.配置文件内容 [mongodb-org-3.6] name=MongoDB Reposit ...
- error: can't copy 'docx\templates\default-docx-template': doesn't exist or not a regular file --------------- Failed building wheel for python-docx; python-docx的安装使用;python操作word
本人第一安装python-docx很不幸就出现了,如下的错误:(如果你也遇到同样的错误,不要慌可以参考下面解决方案,由于第一次处理这种错误,如有不对欢迎大家多多批评指正) 问题所在是因为我们的setu ...
- 2018申请淘宝客AppKey
1.www.alimama.com 申请账号进入后2.进入我的联盟,按下面的步骤 完成以后等待网站审核. 3.审核完成后 按以下的图,申请进入开放平台或得appkey 4.最后就可以进入开放平台申请看 ...
- Golang Go Go Go part3:数据类型及操作
五.Go 基本类型 1.基本类型种类 布尔值: bool 长度 1字节 取值范围 true, false注意事项:不可用数字代表 true 或 false 整型: int/uint 根据运行平台可能为 ...
- gc笔记2
空间分配担保:在发生MinorGC之前,虚拟机会检查老年代最大连续可用是否大于新生代所有对象的空间,如果这个条件成立,则minorgc时安全的
- [转]jenkins2 插件安装
文章来自:http://www.ciandcd.com 文中的代码来自可以从github下载: https://github.com/ciandcd Jenkins的安装包和插件在7个国家有20多个镜 ...
- libguestfs手册(1): 架构
要编辑一个image,则运行下面的命令 guestfish -a ubuntutest.img ><fs> 会弹出一个命令行工具 运行run ><fs> run 我 ...