在C语言中巧用正则表达式

From: http://blog.chinaunix.net/space.php?uid=20435679&do=blog&id=1680220

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



编译正则表达式



为了提高效率,在将一个字符串与正则表达式进行比较之前,首先要用regcomp()函数对它进行编译,将其转化为regex_t结构:

int regcomp(regex_t *preg, const char *regex, int cflags);

Param

参数regex是一个字符串,它代表将要被编译的正则表达式;

参数preg指向一个声明为regex_t的数据结构,用来保存编译结果;

参数cflags决定了正则表达式该如何被处理的细节。 

Return

如果函数regcomp()执行成功,并且编译结果被正确填充到preg中后,函数将返回0,

任何其它的返回结果都代表有某种错误产生。 



匹配正则表达式 



一旦用regcomp()函数成功地编译了正则表达式,接下来就可以调用regexec()函数完成模式匹配: 

int regexec( const regex_t *preg,

const char *string ,

size_t nmatch,

regmatch_t pmatch[],

int eflags

);

typedef struct

{

regoff_t rm_so;

regoff_t rm_eo;

} regmatch_t;

Param

参数preg指向编译后的正则表达式,

参数string是将要进行匹配的字符串,

参数nmatch和pmatch则用于把匹配结果返回给调用程序,

参数eflags决定了匹配的细节。 

ReMark

在调用函数regexec()进行模式匹配的过程中,可能在字符串string中会有多处与给定的正则表达式相匹配,参数pmatch就是用来保存这些匹配位置的,而参数nmatch则告诉函数regexec()最多可以把多少个匹配结果填充到pmatch数组中。当regexec()函数成功返回时,从string+pmatch[0].rm_so到string+pmatch[0].rm_eo是第一个匹配的字符串,而从string+pmatch[1].rm_so到string+pmatch[1].rm_eo,则是第二个匹配的字符串,依此类推。 



释放正则表达式 



无论什么时候,当不再需要已经编译过的正则表达式时,都应该调用函数regfree()将其释放,以免产生内存泄漏。 



void regfree(regex_t *preg);



函数regfree()不会返回任何结果,它仅接收一个指向regex_t数据类型的指针,这是之前调用regcomp()函数所得到的编译结果。 



如果在程序中针对同一个regex_t结构调用了多次regcomp()函数,POSIX标准并没有规定是否每次都必须调用regfree()函数进行释放,但建议每次调用regcomp()函数对正则表达式进行编译后都调用一次regfree()函数,以尽早释放占用的存储空间。 



报告错误信息 



如果调用函数regcomp()或regexec()得到的是一个非0的返回值,则表明在对正则表达式的处理过程中出现了某种错误,此时可以通过调用函数regerror()得到详细的错误信息。 

size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);

Param

参数errcode 是来自函数regcomp()或regexec()的错误代码,

参数preg 是由函数regcomp()得到的编译结果,

其目的是把格式化消息所必须的上下文提供给regerror()函数。

参数errbuf_size指明的最大字节数,





应用正则表达式 



最后给出一个具体的实例,介绍如何在C语言程序中处理正则表达式。 



#include <stdio.h>

#include <sys/types.h>

#include <regex.h>

/* 取子串的函数 */

static char*

substr (const char*str, unsigned start, unsigned end)

{

unsigned n = end - start;

static char stbuf[256];

strncpy(stbuf, str + start, n);

stbuf[n] = 0; return stbuf;

}

/* 主程序 */

int

main(int argc, char** argv)

{

char * pattern;

int x, z, lno = 0, cflags = 0;

char ebuf[128], lbuf[256];

regex_t reg;

regmatch_t pm[10];

const size_t nmatch = 10;

/* 编译正则表达式*/

pattern = argv[1];

z = regcomp(?, pattern, cflags);

if (z != 0)

{

regerror(z, ?, ebuf, sizeof(ebuf));

fprintf(stderr, "%s: pattern '%s' \n", ebuf, pattern);

return 1;

}

/* 逐行处理输入的数据 */

while(fgets(lbuf, sizeof(lbuf), stdin))

{

++lno;

if ((z = strlen(lbuf)) > 0 && lbuf[z-1] == '\n')

lbuf[z - 1] = 0;

/* 对每一行应用正则表达式进行匹配 */

z = regexec(?, lbuf, nmatch, pm, 0);

if (z == REG_NOMATCH)

continue;

else if (z != 0)

{

regerror(z, ?, ebuf, sizeof(ebuf));

fprintf(stderr, "%s: regcom('%s')\n", ebuf, lbuf);

return 2;

}

/* 输出处理结果 */

for (x = 0; x < nmatch && pm[x].rm_so != -1; ++ x)

{

if (!x)

printf("%04d: %s\n", lno, lbuf);

printf(" $%d='%s'\n", x, substr(lbuf, pm[x].rm_so, pm[x].rm_eo));

}

}

/* 释放正则表达式 */

regfree(?);

return 0;

}



上述程序负责从命令行获取正则表达式,然后将其运用于从标准输入得到的每行数据,并打印出匹配结果。执行下面的命令可以编译并执行该程序: 

# gcc regexp.c -o regexp

# ./regexp 'regex[a-z]*' < regexp.c

0003: #include <regex.h> $0='regex'

0027: regex_t reg; $0='regex'

0054: z = regexec(?, lbuf, nmatch, pm, 0); $0='regexec'





小结 



对那些需要进行复杂数据处理的程序来说,正则表达式无疑是一个非常有用的工具。本文重点在于阐述如何在C语言中利用正则表达式来简化字符串处理,以便在数据处理方面能够获得与Perl语言类似的灵活性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/406618.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[笑]每个人都有脑袋脱线的时候……

每个人的脑子在一霎间短路时会做出好笑的事情来&#xff0c;我也是&#xff0c;不过现在让我想还真想不起来&#xff0c;只是在看到下面这篇文章时心里会有似曾相识的感觉&#xff0c;转来让大家感受一下&#xff1a;洗衣服时想吐痰&#xff0c;旁边是马桶&#xff0c;结果一口…

Taro+react开发(60) 第三方icon使用

<AtIconprefixClass"icon"value{isLike true ? "icon-like-select" : "icon-like-default"}size"14"color{isLike true ? "#FF7F00" : "#999"}onClick{() > this.handleIsLike()}></AtIcon>

middlegenidenbsp;nbsp;eclipsenbsp;的插件

eclipse 的插件很好安装的.拖进eclipse的文件夹.加到plugins和features里. 加到eclipse jee里..没反应. 只好加到eclipse j2se里. 可以的. 重要的是这个 学校发的书说只有oracle需要设category和schema. 坑人. 说只就要严谨些 之后的就不用说了 转载于:https://www.cnblog…

mint-ui修改样式的小技巧

1.前言&#xff1a;不是正经的前端&#xff0c;所以很多东西无法注意和知道&#xff0c;就知道一点记录一点好了。 2.之前想修改mint-ui的样式&#xff0c;但是官方文档丝毫未提及&#xff08;也许前端人员都知道如何修改???&#xff09;,后面通过两种方式可以进行mint-ui的…

C语言正则表达式regex

From: http://hi.baidu.com/david_jlu/blog/item/87ada1dbb9af6a60d0164eda.html 正则表达式在linux下应用非常广泛&#xff0c;经常使用sed、awk、grep、vi、emacs等都支持正则表达式&#xff0c;处理最好的莫过于perl&#xff0c;perl把正则表达式内置到语言内&#xff0c;使…

PL/SQL块中不能直接执行DDL语句(错误)

在PL/SQL块中不能直接执行DDL语句(后篇批量删除表时却明明在PL/SQL块中使用了DROP&#xff0c;而且执行成功&#xff0c;厄...自打三十大板...谁来救我...)declarev_string varchar2(1000);beginv_string:create table dm_test as select * from dm_mpg_test where nyr20…

立足优势,你的网站会更精彩

前几天跟一个做培训的朋友喝茶&#xff0c;聊天期间我问他们公司主要做哪些方面的培训&#xff0c;他笑着说他们公司的业务范围可广了&#xff0c;IT培训&#xff0c;MBA考辅&#xff0c;婴幼儿教育&#xff0c;英语培训......言语中流露出无比的自豪&#xff0c;我最后问了一句…

POSIX风格正则表达式

From: http://blog.chinaunix.net/space.php?uid20501242&doblog&id1940007 4.9 POSIX风格正则表达式 POSIX-Style Regular Expressions POSIX 你已经了解了正则表达式的基础知识&#xff0c;接下来我们可以讨论一下其细节。POSIX风格的正则表达式使用Unix地区系统…

Spring对事务管理的支持的发展历程(基础篇)

1、问题Java代码 Connection conn DataSourceUtils.getConnection(); //开启事务 conn.setAutoCommit(false); try { Object retVal callback.doInConnection(conn); conn.commit(); //提交事务 return retVal; }catch (Excep…

最新xampp下安装mod_security,mod_evasive,mod-cband笔记

来源&#xff1a;纯月部落mod_security官方的文档有一些问题&#xff0c;亲手装了一遍&#xff0c;现将问题记录如下Windows xampp版本 假设xampp安装在D:\xampp1 下载mod_security-2.5.9-win32.zip&#xff0c;解压缩2 将libxml2.dll拷贝到D:\xampp\apache\bin下面3 将mod_sec…

Bash字符串处理(与Java对照) - 17.判断是否以另外的字符串结尾

From: http://codingstandards.iteye.com/blog/1187353 In Java String.endsWith oolean endsWith(String suffix) 测试此字符串是否以指定的后缀结束。 StringUtils.endsWith & StringUtils.endsWithIgnoreCase & StringUtils.endsWithAny org.apache.c…

[转载]用c写PHP的扩展接口(php5,c++)

原文&#xff3b;http://bugs.tutorbuddy.com/php5cpp/php5cpp/&#xff3d;第1节. 开始之前开始前&#xff0c;我要说明&#xff1a;这篇文章所描述的主要是在UNIX的PHP环境上的。另外一点我要说明的是&#xff1a;文中所介绍的方法在PHP 4.3.x和PHP 5下都是可行的。尽管我们在…

web前端——transform变形 旋转角度正负的判断

在使用CSS的transform的变形效果的时候&#xff0c;总是被这个角度的正负搞的头大&#xff0c;特意写出来&#xff0c;和大家分享 首先&#xff0c;我们要学会怎么看 假设需要围绕x轴做旋转&#xff0c;那么我们将x轴的正向指向我们自己&#xff0c;然后再看顺时针和逆时针&am…

话里话外:成功的ERP需要全程的流程变革(三)

成功的ERP需要全程的流程变革流程变革最佳实践5步走流程变革的最佳实践&#xff0c;是将一个颇具风险的流程重组过程分解为几个分步实现的步骤&#xff0c;并与ERP的实施同步开展&#xff0c;再经过几轮优化改进的循环&#xff0c;达到变革的目标——提高流程的效益和效率。伴随…

Bash字符串处理(与Java对照) - 18.格式化字符串

From: http://codingstandards.iteye.com/blog/1198098 In Java class Formatter 参见&#xff1a;http://download.oracle.com/javase/6/docs/api/java/util/Formatter.html#syntax String.format static String format(String format, Object... args) 使用指定…

Unity基础知识学习笔记二

1&#xff0c;object Instantiate(object original,Vector3 position,Quaternion rotation) 克隆原始物体&#xff0c;并返回克隆物体。例如&#xff1a;Instantiate(prefab,new Vector3(1,1,1),Qutaternion.identity);克隆一个prefab物体。2,InputManager,输入管理器&#xff…