日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2023/12/9 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在C语言中巧用正则表达式 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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

標(biāo)準(zhǔn)的C和C++都不支持正則表達(dá)式,但有一些函數(shù)庫可以輔助C/C++程序員完成這一功能,其中最著名的當(dāng)數(shù)Philip Hazel的Perl-Compatible Regular Expression庫,許多Linux發(fā)行版本都帶有這個(gè)函數(shù)庫。



編譯正則表達(dá)式



為了提高效率,在將一個(gè)字符串與正則表達(dá)式進(jìn)行比較之前,首先要用regcomp()函數(shù)對(duì)它進(jìn)行編譯,將其轉(zhuǎn)化為regex_t結(jié)構(gòu):

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

Param

參數(shù)regex是一個(gè)字符串,它代表將要被編譯的正則表達(dá)式;

參數(shù)preg指向一個(gè)聲明為regex_t的數(shù)據(jù)結(jié)構(gòu),用來保存編譯結(jié)果;

參數(shù)cflags決定了正則表達(dá)式該如何被處理的細(xì)節(jié)。?

Return

如果函數(shù)regcomp()執(zhí)行成功,并且編譯結(jié)果被正確填充到preg中后,函數(shù)將返回0,

任何其它的返回結(jié)果都代表有某種錯(cuò)誤產(chǎn)生。?



匹配正則表達(dá)式?



一旦用regcomp()函數(shù)成功地編譯了正則表達(dá)式,接下來就可以調(diào)用regexec()函數(shù)完成模式匹配:?

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

參數(shù)preg指向編譯后的正則表達(dá)式,

參數(shù)string是將要進(jìn)行匹配的字符串,

參數(shù)nmatch和pmatch則用于把匹配結(jié)果返回給調(diào)用程序,

參數(shù)eflags決定了匹配的細(xì)節(jié)。?

ReMark

在調(diào)用函數(shù)regexec()進(jìn)行模式匹配的過程中,可能在字符串string中會(huì)有多處與給定的正則表達(dá)式相匹配,參數(shù)pmatch就是用來保存這些匹配位置的,而參數(shù)nmatch則告訴函數(shù)regexec()最多可以把多少個(gè)匹配結(jié)果填充到pmatch數(shù)組中。當(dāng)regexec()函數(shù)成功返回時(shí),從string+pmatch[0].rm_so到string+pmatch[0].rm_eo是第一個(gè)匹配的字符串,而從string+pmatch[1].rm_so到string+pmatch[1].rm_eo,則是第二個(gè)匹配的字符串,依此類推。?



釋放正則表達(dá)式?



無論什么時(shí)候,當(dāng)不再需要已經(jīng)編譯過的正則表達(dá)式時(shí),都應(yīng)該調(diào)用函數(shù)regfree()將其釋放,以免產(chǎn)生內(nèi)存泄漏。?



void regfree(regex_t *preg);



函數(shù)regfree()不會(huì)返回任何結(jié)果,它僅接收一個(gè)指向regex_t數(shù)據(jù)類型的指針,這是之前調(diào)用regcomp()函數(shù)所得到的編譯結(jié)果。?



如果在程序中針對(duì)同一個(gè)regex_t結(jié)構(gòu)調(diào)用了多次regcomp()函數(shù),POSIX標(biāo)準(zhǔn)并沒有規(guī)定是否每次都必須調(diào)用regfree()函數(shù)進(jìn)行釋放,但建議每次調(diào)用regcomp()函數(shù)對(duì)正則表達(dá)式進(jìn)行編譯后都調(diào)用一次regfree()函數(shù),以盡早釋放占用的存儲(chǔ)空間。?



報(bào)告錯(cuò)誤信息?



如果調(diào)用函數(shù)regcomp()或regexec()得到的是一個(gè)非0的返回值,則表明在對(duì)正則表達(dá)式的處理過程中出現(xiàn)了某種錯(cuò)誤,此時(shí)可以通過調(diào)用函數(shù)regerror()得到詳細(xì)的錯(cuò)誤信息。?

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

Param

參數(shù)errcode 是來自函數(shù)regcomp()或regexec()的錯(cuò)誤代碼,

參數(shù)preg 是由函數(shù)regcomp()得到的編譯結(jié)果,

其目的是把格式化消息所必須的上下文提供給regerror()函數(shù)。

參數(shù)errbuf_size指明的最大字節(jié)數(shù),





應(yīng)用正則表達(dá)式?



最后給出一個(gè)具體的實(shí)例,介紹如何在C語言程序中處理正則表達(dá)式。?



#include <stdio.h>

#include <sys/types.h>

#include <regex.h>

/* 取子串的函數(shù) */

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;

/* 編譯正則表達(dá)式*/

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;

}

/* 逐行處理輸入的數(shù)據(jù) */

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

{

++lno;

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

lbuf[z - 1] = 0;

/* 對(duì)每一行應(yīng)用正則表達(dá)式進(jìn)行匹配 */

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;

}

/* 輸出處理結(jié)果 */

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));

}

}

/* 釋放正則表達(dá)式 */

regfree(?);

return 0;

}



上述程序負(fù)責(zé)從命令行獲取正則表達(dá)式,然后將其運(yùn)用于從標(biāo)準(zhǔn)輸入得到的每行數(shù)據(jù),并打印出匹配結(jié)果。執(zhí)行下面的命令可以編譯并執(zhí)行該程序:?

# 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'





小結(jié)?



對(duì)那些需要進(jìn)行復(fù)雜數(shù)據(jù)處理的程序來說,正則表達(dá)式無疑是一個(gè)非常有用的工具。本文重點(diǎn)在于闡述如何在C語言中利用正則表達(dá)式來簡(jiǎn)化字符串處理,以便在數(shù)據(jù)處理方面能夠獲得與Perl語言類似的靈活性。

總結(jié)

以上是生活随笔為你收集整理的在C语言中巧用正则表达式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。