c語言的正則匹配函數(shù) c語言正則表達(dá)式函數(shù)庫(kù)
C語言怎么用正則表達(dá)式
由于它可以極大地簡(jiǎn)化處理字符串時(shí)的復(fù)雜度,因此現(xiàn)在已經(jīng)在許多 L i n u x 實(shí)用工具中得到了應(yīng)用。千萬不要以為正則表達(dá)式只是 P e r l 、 P y t h o n 、 B a s h 等腳本語言的專利,作為 C 語言程序員,用戶同樣可以在自己的程序中運(yùn)用正則表達(dá)式。標(biāo)準(zhǔn)的 C 和 C + + 都不支持正則表達(dá)式,但有一些函數(shù)庫(kù)可以輔助 C / C + + 程序員完成這一功能,其中最著名的當(dāng)數(shù) P h i l i p H a z e l 的 P e r l - C o m p a t i b l e R e g u l a r E x p r e s s i o n 庫(kù),許多 L i n u x 發(fā)行版本都帶有這個(gè)函數(shù)庫(kù)。編譯正則表達(dá)式為了提高效率,在將一個(gè)字符串與正則表達(dá)式進(jìn)行比較之前,首先要用 r e g c o m p ( ) 函數(shù)對(duì)它進(jìn)行編譯,將其轉(zhuǎn)化為 r e g e x _ t 結(jié)構(gòu): i n t r e g c o m p ( r e g e x _ t * p r e g , c o n s t c h a r * r e g e x , i n t c f l a g s ) ; 參數(shù) r e g e x 是一個(gè)字符串,它代表將要被編譯的正則表達(dá)式;參數(shù) p r e g 指向一個(gè)聲明為 r e g e x _ t 的數(shù)據(jù)結(jié)構(gòu),用來保存編譯結(jié)果;參數(shù) c f l a g s 決定了正則表達(dá)式該如何被處理的細(xì)節(jié)。如果函數(shù) r e g c o m p ( ) 執(zhí)行成功,并且編譯結(jié)果被正確填充到 p r e g 中后,函數(shù)將返回 0 ,任何其它的返回結(jié)果都代表有某種錯(cuò)誤產(chǎn)生。匹配正則表達(dá)式一旦用 r e g c o m p ( ) 函數(shù)成功地編譯了正則表達(dá)式,接下來就可以調(diào)用 r e g e x e c ( ) 函數(shù)完成模式匹配: i n t r e g e x e c ( c o n s t r e g e x _ t * p r e g , c o n s t c h a r * s t r i n g , s i z e _ t n m a t c h , r e g m a t c h _ t p m a t c h [ ] , i n t e f l a g s ) ; t y p e d e f s t r u c t { r e g o f f _ t r m _ s o ; r e g o f f _ t r m _ e o ; } r e g m a t c h _ t ; 參數(shù) p r e g 指向編譯后的正則表達(dá)式,參數(shù) s t r i n g 是將要進(jìn)行匹配的字符串,而參數(shù) n m a t c h 和 p m a t c h 則用于把匹配結(jié)果返回給調(diào)用程序,最后一個(gè)參數(shù) e f l a g s 決定了匹配的細(xì)節(jié)。在調(diào)用函數(shù) r e g e x e c ( ) 進(jìn)行模式匹配的過程中,可能在字符串 s t r i n g 中會(huì)有多處與給定的正則表達(dá)式相匹配,參數(shù) p m a t c h 就是用來保存這些匹配位置的,而參數(shù) n m a t c h 則告訴函數(shù) r e g e x e c ( ) 最多可以把多少個(gè)匹配結(jié)果填充到 p m a t c h 數(shù)組中。當(dāng) r e g e x e c ( ) 函數(shù)成功返回時(shí),從 s t r i n g + p m a t c h [ 0 ] . r m _ s o 到 s t r i n g + p m a t c h [ 0 ] . r m _ e o 是第一個(gè)匹配的字符串,而從 s t r i n g + p m a t c h [ 1 ] . r m _ s o 到 s t r i n g + p m a t c h [ 1 ] . r m _ e o ,則是第二個(gè)匹配的字符串,依此類推。釋放正則表達(dá)式無論什么時(shí)候,當(dāng)不再需要已經(jīng)編譯過的正則表達(dá)式時(shí),都應(yīng)該調(diào)用函數(shù) r e g f r e e ( ) 將其釋放,以免產(chǎn)生內(nèi)存泄漏。 v o i d r e g f r e e ( r e g e x _ t * p r e g ) ; 函數(shù) r e g f r e e ( ) 不會(huì)返回任何結(jié)果,它僅接收一個(gè)指向 r e g e x _ t 數(shù)據(jù)類型的指針,這是之前調(diào)用 r e g c o m p ( ) 函數(shù)所得到的編譯結(jié)果。如果在程序中針對(duì)同一個(gè) r e g e x _ t 結(jié)構(gòu)調(diào)用了多次 r e g c o m p ( ) 函數(shù), P O S I X 標(biāo)準(zhǔn)并沒有規(guī)定是否每次都必須調(diào)用 r e g f r e e ( ) 函數(shù)進(jìn)行釋放,但建議每次調(diào)用 r e g c o m p ( ) 函數(shù)對(duì)正則表達(dá)式進(jìn)行編譯后都調(diào)用一次 r e g f r e e ( ) 函數(shù),以盡早釋放占用的存儲(chǔ)空間。報(bào)告錯(cuò)誤信息如果調(diào)用函數(shù) r e g c o m p ( ) 或 r e g e x e c ( ) 得到的是一個(gè)非 0 的返回值,則表明在對(duì)正則表達(dá)式的處理過程中出現(xiàn)了某種錯(cuò)誤,此時(shí)可以通過調(diào)用函數(shù) r e g e r r o r ( ) 得到詳細(xì)的錯(cuò)誤信息。 s i z e _ t r e g e r r o r ( i n t e r r c o d e , c o n s t r e g e x _ t * p r e g , c h a r * e r r b u f , s i z e _ t e r r b u f _ s i z e ) ; 參數(shù) e r r c o d e 是來自函數(shù) r e g c o m p ( ) 或 r e g e x e c ( ) 的錯(cuò)誤代碼,而參數(shù) p r e g 則是由函數(shù) r e g c o m p ( ) 得到的編譯結(jié)果,其目的是把格式化消息所必須的上下文提供給 r e g e r r o r ( ) 函數(shù)。在執(zhí)行函數(shù) r e g e r r o r ( ) 時(shí),將按照參數(shù) e r r b u f _ s i z e 指明的最大字節(jié)數(shù),在 e r r b u f 緩沖區(qū)中填入格式化后的錯(cuò)誤信息,同時(shí)返回錯(cuò)誤信息的長(zhǎng)度。應(yīng)用正則表達(dá)式最后給出一個(gè)具體的實(shí)例,介紹如何在 C 語言程序中處理正則表達(dá)式。 # i n c l u d e s t d i o . h ; # i n c l u d e s y s / t y p e s . h ; # i n c l u d e r e g e x . h ; / * 取子串的函數(shù) * / s t a t i c c h a r * s u b s t r ( c o n s t c h a r * s t r , u n s i g n e d s t a r t , u n s i g n e d e n d ) { u n s i g n e d n = e n d - s t a r t ; s t a t i c c h a r s t b u f [ 2 5 6 ] ; s t r n c p y ( s t b u f , s t r + s t a r t , n ) ; s t b u f [ n ] = 0 ; r e t u r n s t b u f ; } / * 主程序 * / i n t m a i n ( i n t a r g c , c h a r * * a r g v ) { c h a r * p a t t e r n ; i n t x , z , l n o = 0 , c f l a g s = 0 ; c h a r e b u f [ 1 2 8 ] , l b u f [ 2 5 6 ] ; r e g e x _ t r e g ; r e g m a t c h _ t p m [ 1 0 ] ; c o n s t s i z e _ t n m a t c h = 1 0 ; / * 編譯正則表達(dá)式 * / p a t t e r n = a r g v [ 1 ] ; z = r e g c o m p ( r e g , p a t t e r n , c f l a g s ) ; i f ( z ! = 0 ) { r e g e r r o r ( z , r e g , e b u f , s i z e o f ( e b u f ) ) ; f p r i n t f ( s t d e r r , " % s : p a t t e r n ' % s ' \ n " , e b u f , p a t t e r n ) ; r e t u r n 1 ; } / * 逐行處理輸入的數(shù)據(jù) * / w h i l e ( f g e t s ( l b u f , s i z e o f ( l b u f ) , s t d i n ) ) { + + l n o ; i f ( ( z = s t r l e n ( l b u f ) ) ; 0 l b u f [ z - 1 ] = = ' \ n ' ) l b u f [ z - 1 ] = 0 ; / * 對(duì)每一行應(yīng)用正則表達(dá)式進(jìn)行匹配 * / z = r e g e x e c ( r e g , l b u f , n m a t c h , p m , 0 ) ; i f ( z = = R E G _ N O M A T C H ) c o n t i n u e ; e l s e i f ( z ! = 0 ) { r e g e r r o r ( z , r e g , e b u f , s i z e o f ( e b u f ) ) ; f p r i n t f ( s t d e r r , " % s : r e g c o m ( ' % s ' ) \ n " , e b u f , l b u f ) ; r e t u r n 2 ; } / * 輸出處理結(jié)果 * / f o r ( x = 0 ; x n m a t c h p m [ x ] . r m _ s o ! = - 1 ; + + x ) { i f ( ! x ) p r i n t f ( " % 0 4 d : % s \ n " , l n o , l b u f ) ; p r i n t f ( " $ % d = ' % s ' \ n " , x , s u b s t r ( l b u f , p m [ x ] . r m _ s o , p m [ x ] . r m _ e o ) ) ; } } / * 釋放正則表達(dá)式 * / r e g f r e e ( r e g ) ; r e t u r n 0 ; } 上述程序負(fù)責(zé)從命令行獲取正則表達(dá)式,然后將其運(yùn)用于從標(biāo)準(zhǔn)輸入得到的每行數(shù)據(jù),并打印出匹配結(jié)果。執(zhí)行下面的命令可以編譯并執(zhí)行該程序: # g c c r e g e x p . c - o r e g e x p # . / r e g e x p ' r e g e x [ a - z ] * ' r e g e x p . c 0 0 0 3 : # i n c l u d e r e g e x . h ; $ 0 = ' r e g e x ' 0 0 2 7 : r e g e x _ t r e g ; $ 0 = ' r e g e x ' 0 0 5 4 : z = r e g e x e c ( r e g , l b u f , n m a t c h , p m , 0 ) ; $ 0 = ' r e g e x e c ' 小結(jié)對(duì)那些需要進(jìn)行復(fù)雜數(shù)據(jù)處理的程序來說,正則表達(dá)式無疑是一個(gè)非常有用的工具。本文重點(diǎn)在于闡述如何在 C 語言中利用正則表達(dá)式來簡(jiǎn)化字符串處理,以便在數(shù)據(jù)處理方面能夠獲得與 P e r l 語言類似的靈活性。
如何用正則表達(dá)式匹配到C語言中的函數(shù)實(shí)現(xiàn)部分的函數(shù)頭部分。
一些補(bǔ)充:腳本是ruby,領(lǐng)會(huì)精神就行了……
/regexp/m 多行模式正則表達(dá)式
/regexp/ 單行模式正則表達(dá)式
=~ 若匹配返回第一個(gè)匹配的位置,不匹配則返回nil
$1,$2 反向引用(分別對(duì)應(yīng)第1,2個(gè)括號(hào))
string[start...end] 截取字符串從start到end-1的那段dup 復(fù)制sub,gsub,sub!,gsub! 字符串替換,感嘆號(hào)表示替換自身,沒感嘆號(hào)則返回新串正則表達(dá)式語法全世界都大同小異,就不解釋了……
用C語言完成一個(gè)正則表達(dá)式的匹配: 字符串中只有*和?是可變字符且位置和個(gè)數(shù)不固定,其他的字符位置固定
#includestdio.h
#includestring.h
#include stdlib.h
//1、'?'很好處理,只要在原有的定位函數(shù)中加一點(diǎn)點(diǎn)就行:
int index(char *s,char *t,int pos)
{
int i=pos,j=0,lens=strlen(s),lent=strlen(t);
while(ilensjlent)
{
if(s[i]==t[j]||t[j]=='?')
{
++i;
++j;
}
else
{
i=i-j+1;
j=0;
}
}
if(j==lent)return i-lent;
else return -1;
}
/*2、'*'的處理有些麻煩,很自然的想法是'*'把整個(gè)T串分成若干不含'*'的子串,
拿這些子串依次匹配S串。
按這樣的方法可以把S串分成兩類:
A、T=T1*T2*...Tn*,其中Ti為不含'*'的子串,且不為空(T1可為空)。
B、T=T1*T2*...Tn
二者的差別只在于尾部是否有'*'。
拿T匹配S,
首先 T1匹配S頭部,index(s,t1,0)==0
然后 用循環(huán)完成后面的匹配,從前一次匹配后的末尾位置開始向后匹配,
如果匹配成功再把末尾位置記錄下來。這里只用了最左匹配,為什么就足夠了呢?
比如實(shí)際中的情況T1串可能在S串不止出現(xiàn)一次,為什么只考慮最左一個(gè)呢?
因?yàn)檎麄€(gè)匹配過程是從左向右,最左匹配可以保證余下的S子中最長(zhǎng),更有利于后面T子串的匹配成功,
試想如果T1最左匹配不成功,靠右一些有可能成功嗎?
例:T="*is*a*" S="this is a program"
T 子串"is"在S中有出現(xiàn)兩個(gè)位置,匹配的時(shí)候只需要考慮最左邊那個(gè)"is"就行了,
因?yàn)樽钭筮叺?is"匹配成功后,余下的S子串是" is a program",余下的T子串是"*a",
最左匹配可使余下的S子串最長(zhǎng),匹配的可能最大,最容易匹配的情況已經(jīng)驗(yàn)證了,
就不用再做無用功了。
*/
int match(char *s,char *t)
{
int i=0,j=0,lens=strlen(s),lent=strlen(t);
char buf[128];
int bufp=0;
while(jlentt[j]!='*')
{
buf[bufp]=t[j];
++bufp;++j;
}
buf[bufp]='\0';
if(index(s,buf,0)!=0)return 0;
i=bufp;
while(1)
{
while(jlentt[j]=='*')++j;
if(j==lent)return 1;
bufp=0;
while(jlentt[j]!='*')
{
buf[bufp]=t[j];
++bufp;++j;
}
buf[bufp]='\0';
if(j==lent)
{
if(index(s,buf,i)!=lens-bufp)return 0;
return 1;
}
if((i=index(s,buf,i))==-1)return 0;
i+=bufp;
}
}
void main()
{
char s[128];
char t[128]="mad*se$?243*.xml";
memset(s,'\0',128);//初始化s
printf("輸入字符串,進(jìn)行匹配\n");
gets(s);
if(match(s,t))
printf("匹配\n");
else
printf("不匹配\n");
}
上一篇:func函數(shù)+在C語言 func函數(shù)在c語言中
欄 目:C語言
下一篇:c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用函數(shù)刪除字符
本文標(biāo)題:c語言的正則匹配函數(shù) c語言正則表達(dá)式函數(shù)庫(kù)
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/17107.html
您可能感興趣的文章
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用函數(shù)刪除字符
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言中對(duì)數(shù)函數(shù)的表達(dá)式 c語言中對(duì)數(shù)怎么表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段函數(shù)
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排序法函數(shù)
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段函數(shù)
- 04-02C語言中怎么打出三角函數(shù) c語言中怎么打出三角函數(shù)的值
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求階乘
- 01-10c語言求1+2+...+n的解決方法


閱讀排行
- 1C語言 while語句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對(duì)數(shù)函數(shù)的表達(dá)式 c語言中對(duì)
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 04-02jquery與jsp,用jquery
- 01-10delphi制作wav文件的方法