标准的C和C++都不支持正则表达式,但有一些函数库可以辅助C/C++程序员完成这一功能,其中最著名的当数Philip Hazel的Perl-Compatible
Regular Expression库,许多Linux发行版本都带有这个函数库。

可以参照:http://midatl.radford.edu/docs/C/Pattern-Matching.html#Pattern-Matching

C语言处理正则表达式常用的函数有regcomp()、regexec()、regfree()和regerror(),一般分为三个步骤,如下所示:

C语言中使用正则表达式一般分为三步:
  1. 编译正则表达式 regcomp()
  2. 匹配正则表达式 regexec()
  3. 释放正则表达式 regfree()

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

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

这个函数把指定的正则表达式pattern编译成一种特定的数据格式compiled,这样可以使匹配更有效。函数regexec 会使用这个数据在目标文本串中进行模式匹配。执行成功返回0。  

参数说明:

①regex_t 是一个结构体数据类型,用来存放编译后的正则表达式,它的成员re_nsub 用来存储正则表达式中的子正则表达式的个数,子正则表达式就是用圆括号包起来的部分表达式。

②pattern 是指向我们写好的正则表达式的指针。

③cflags 有如下4个值或者是它们或运算(|)后的值:

REG_EXTENDED 以功能更加强大的扩展正则表达式的方式进行匹配。

REG_ICASE 匹配字母时忽略大小写。

REG_NOSUB 不用存储匹配后的结果。

REG_NEWLINE 识别换行符,这样'$'就可以从行尾开始匹配,'^'就可以从行的开头开始匹配。



2. int regexec (regex_t *compiled, char *string, size_t nmatch, regmatch_t matchptr [], int eflags)

当我们编译好正则表达式后,就可以用regexec 匹配我们的目标文本串了,如果在编译正则表达式的时候没有指定cflags的参数为REG_NEWLINE,则默认情况下是忽略换行符的,也就是把整个文本串当作一个字符串处理。执行成功返回0。

regmatch_t 是一个结构体数据类型,在regex.h中定义:             

typedef struct

{

   regoff_t rm_so;

   regoff_t rm_eo;

} regmatch_t;

成员rm_so 存放匹配文本串在目标串中的开始位置,rm_eo 存放结束位置。通常我们以数组的形式定义一组这样的结构。因为往往我们的正则表达式中还包含子正则表达式。数组0单元存放主正则表达式位置,后边的单元依次存放子正则表达式位置。

参数说明:

①compiled 是已经用regcomp函数编译好的正则表达式。

②string 是目标文本串。

③nmatch 是regmatch_t结构体数组的长度。

④matchptr regmatch_t类型的结构体数组,存放匹配文本串的位置信息。

⑤eflags 有两个值

REG_NOTBOL 按我的理解是如果指定了这个值,那么'^'就不会从我们的目标串开始匹配。总之我到现在还不是很明白这个参数的意义;

REG_NOTEOL 和上边那个作用差不多,不过这个指定结束end of line。



3. void regfree (regex_t *compiled)

当我们使用完编译好的正则表达式后,或者要重新编译其他正则表达式的时候,我们可以用这个函数清空compiled指向的regex_t结构体的内容,请记住,如果是重新编译的话,一定要先清空regex_t结构体。



4. size_t regerror (int errcode, regex_t *compiled, char *buffer, size_t length)

当执行regcomp 或者regexec 产生错误的时候,就可以调用这个函数而返回一个包含错误信息的字符串。

参数说明:

①errcode 是由regcomp 和 regexec 函数返回的错误代号。

②compiled 是已经用regcomp函数编译好的正则表达式,这个值可以为NULL。

③buffer 指向用来存放错误信息的字符串的内存空间。

④length 指明buffer的长度,如果这个错误信息的长度大于这个值,则regerror 函数会自动截断超出的字符串,但他仍然会返回完整的字符串的长度。所以我们可以用如下的方法先得到错误字符串的长度。

size_t length = regerror (errcode, compiled, NULL, 0);

下面介绍如何在Linux
C中正确使用正则表达式,以查找有关字符串并打印出来为例:

#include <stdio.h>
#include <sys/types.h>
#include <regez.h> in chk_line(int lineno, regex_t *reg,char *line)
{
int rtn,i,len;
regmatch_t pmatch;
char *url,*pbuf; fprintf(stderr,"%4d",lineno);
rtn = regexec(reg,line,1,&pmatch,0);
pbuf = line;
while(rtn == 0)
{
len = pmatch.rm_eo - pmatch.rm_so;
url = (char*)malloc((len+1)*sizeof(char));
memset(url,0,(len+1)*sizeof(char));
memcpy(url,&pbuf[pmatch.rm_so].len);
fprintf(stderr,"%s",url);
free(url);
pbuf += pmatch.rm_eo;
rtn = regexec(reg,pbuf,1,&pmatch,REG_NOTBOL);
}
fprintf(stderr,"/n");
return 0;
}
int chk_file(const char *filename)
{
FILE *fp;
char *pattern = "^(hisencyber)(.com|.com.cn)";
char buf[1024],line[1024];
int rtn,lineno,flag; fp = fopen(filename,"r");
if(fp == NULL)
{
fprintf(stderr,"OPen file failed/n",filename);
return -1;
}
rtn = Regcomp(®,patten,REG_ICASE|REG_EXTENDED);
if(rtn)
{
fprintf(stderr,"compile failed./n");
fclose(fp);
return -1;
}
lineno = 1;
memset(line,0,sizeof(line));
while(fgets(line,sizeof(line),fp)!= NULL)
{
chk_line(lineno++,®,line);
}
fclose(fp);
regefree(®);
return 0;
}
int main (int argc,char *argv[])
{
int rtn;
if(argc != 2)
{
fprintf(stderr,"Usage:chkfileurl <file> /n ");
return 1;
}
rtn = chk_file(argv[1]);
return rtn;
}

正则表达式示例表

字 符 意 义 示 例

* 任意长度的字符串。 a* 表示: 空字符串、aaaa、a…

? 长度为0或者1的字符串。 a? 表示: 空字符串和a。

+ 长度为一个或者多个的字符串。 a+表示:a、aa、aaaaaa…

. 任意字符。 a. 表示:a后跟任意字符。

{} 代表上一规则重复数目、

{1,1,s}包含一组匹配花括号,里面有两个数字和一个字符,表示在指定次数范围内找到字符。 a{3}表示:三个a、

a{1,3}表示:一个到三个a、

a{3,} 表示:大于等于三个a、

{3,7,a}表示在3到7次重复范围内匹配字符a。

[] 集合,代表方括号中任意一个字符。 [ab] 表示:a或者b都可以、

[a-z] 表示:从a到z的字符。

() 组,代表一组字符。 (ab){2}表示:abab。

a/b 同时满足。 a/b表示:字符串a后跟字符串b才能满足要求。

a|b 并列,代表符合a或者符合b都可以 a|b表示: 字符串a或者字符串b都满足要求。

^ 如果放在开头表示代表该规则必须在字符串的开头,其他位置代表字符本身。

如果放在[]中的开头表示对该集合取反,其他位置代表字符本身。 ^a表示:a必须在字符串的开头、

[^a]表示:除了a以外的其他字符。

$ 如果放在最后表示该规则必须放在最后,其他位置代表字符本身。 a$表示:a必须在字符串最后。

/:s 正则表达式用 /:s 表示空格。 a/:sb 匹配 a b。

/:a 正则表达式用 /:a 表示字符与数字。 a/:a 匹配 ab、a6 等。

/:c 正则表达式用 /:c 仅表示字符。 a/:c 匹配 ac等,不匹配a1等。

/:p 正则表达式用 /:p 表示可打印字符。 

/:D 正则表达式用 /:d 仅表示数字。 a/:c 匹配 a1等,不匹配ac等。

/:x00 正则表达式用 /:x00 表示ASCII字符。 

/:r 正则表达式用 /:r 表示回车。 

/:N 正则表达式用 /:d 表示换行。

C语言正则表达式详解 regcomp() regexec() regfree()详解的更多相关文章

  1. 笔记整理——Linux下C语言正则表达式

    Linux下C语言正则表达式使用详解 - Google Chrome (2013/5/2 16:40:37) Linux下C语言正则表达式使用详解 2012年6月6日Neal627 views发表评论 ...

  2. (转)python中调用R语言通过rpy2 进行交互安装配置详解

    python中调用R语言通过rpy2 进行交互安装配置详解(R_USER.R_HOME配置) 2018年11月08日 10:00:11 luqin_ 阅读数:753   python中调用R语言通过r ...

  3. C语言对文件的操作函数用法详解2

    fopen(打开文件) 相关函数 open,fclose 表头文件 #include<stdio.h> 定义函数 FILE * fopen(const char * path,const  ...

  4. C语言对文件的操作函数用法详解1

    在ANSIC中,对文件的操作分为两种方式,即: 流式文件操作 I/O文件操作 一.流式文件操作 这种方式的文件操作有一个重要的结构FILE,FILE在stdio.h中定义如下: typedef str ...

  5. c语言正则表达式

    标准的C和C++都不支持正则表达式,但有一些函数库可以辅助C/C++程序员完成这一功能,其中最著名的当数Philip Hazel的Perl-Compatible Regular Expression库 ...

  6. C语言中的经典例题用javascript怎么解?(一)

    C语言中的经典例题用javascript怎么解?(一) 一.1+2+3+……+100=?        <script type="text/javascript">  ...

  7. ViewPager 详解(二)---详解四大函数

    前言:上篇中我们讲解了如何快速实现了一个滑动页面,但问题在于,PageAdapter必须要重写的四个函数,它们都各有什么意义,在上节的函数内部为什么要这么实现,下面我们就结合Android的API说明 ...

  8. IE8“开发人员工具”使用详解上(各级菜单详解)

    来源: http://www.cnblogs.com/JustinYoung/archive/2009/03/24/kaifarenyuangongju.html IE8“开发人员工具”使用详解上(各 ...

  9. iOS 开发之照片框架详解之二 —— PhotoKit 详解(下)

    本文链接:http://kayosite.com/ios-development-and-detail-of-photo-framework-part-three.html 这里接着前文<iOS ...

随机推荐

  1. VS2015 使用Razor编写MVC视图时,Razor智能提示消失,报各种红线解决方案。

    打开文件夹 Users\<CurrentUser>\AppData\Local\Microsoft\VisualStudio\<version> 删除文件夹 Component ...

  2. linux查找日志技巧

    对于从事web开发的人员来说.服务器上的日志多如牛毛,如何快速从中找出所需信息非常重要,以下是我在工作中用到的查找日志的简单命令,希望能对您有所帮助:   工具/原料   linux SecureCR ...

  3. DIJ产品系列

  4. Solr部署到Tomcat

    1.版本选择 solr-5.3.1.tgz apache-tomcat-8.0.29.tar.gz 2.解压tomcat和solr [root@iZ23exixsjaZ solr]# .tar.gz ...

  5. Combobox

    1.方式一 <select id="cc" class="easyui-combobox" name="dept" style=&qu ...

  6. [转] Fix: Screen Clipping Shortcut In OneNote Not Working After Upgrading To Windows 8.1

    RECOMMENDED: Click here to fix Windows errors and optimize system performance No doubt, OneNote is y ...

  7. 细说IIS异常日志 — 你必须知道的功能

    最近在跟QAD用Webservice搞接口做数据维护,搞的哥那个叫头大,遇到很多问题,系统的log4net根本就无法记录.话说QAD调我某一个接口,可能包含几百个字段,而且QAD是个产品,所以我这边提 ...

  8. Android自学笔记:Git下载源代码

    Info:做J2ME几年了,现在基本没有公司用了,是时候向Android领域进军了. 自学中,难免会有疏漏,有问题请及时提出,共同学习共同进步. 2014-10-13:初版 2014-10-14:添加 ...

  9. org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [41] did not match expected type [java.lang.Integer (n/a)];

    题记:以前记录过一些自己遇到的BUG,这个行为,让我一看报错的提示信息就能定位到问题的所在,后来记得比较多了,好多是重复性的再加上比较忙就没有详细的记录了,今天的工作量比较小,就顺便记录一下,以便以后 ...

  10. 搭建fedora开发环境 common lisp, c++, go

    第三方软件库: http://download1.rpmfusion.org/free/fedora/releases/25/Everything/x86_64/os/repoview/index.h ...