GNU C 規則表示式入門(轉)
GNU C 規則表示式入門(轉)[@more@]用過Perl的朋友應該都它提供了規則表示式功能,所以使得用perl 進行文字處理非常方便。本人最近試用了一下 GNU C 的規則表示式功能, 發現使用起來也很簡單,只是覺得支援的不夠強大,不能夠進行文字的替換,只能進行文字的查詢,至少目前我是 沒有發現基於規則表示式的 文字替換功能。 下面我就簡單的介紹一下GNU C 的規則表示式使用方法,有理解不對的地方,還請朋友們多指正。 在GNU C 中要使用規則表示式,需要用到以下幾個函式。(定義在/usr/include/regex.h檔案中) * int regcomp (regex_t *compiled, const char *pattern, int cflags) * int regexec (regex_t *compiled, char *string, size_t nmatch, regmatch_t matchptr [], int eflags) * void regfree (regex_t *compiled) * size_t regerror (int errcode, regex_t *compiled, char *buffer, size_t length) 下面我就介紹分別一下這幾個函式和它用到的一些資料型別。 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 是一個結構體資料型別,成員rm_so 存放匹配文字串在目標串中的開始位置,rm_eo 存放結束位 置。通常我們以陣列的形式定義 一組這樣的結構。因為往往我們的規則表示式中還包含子規則表示式。陣列0單元存放主規則表示式位置,後邊的 單元依次存放子規則表示式位 置。 compiled 是已經用regcomp函式編譯好的規則表示式。 string 是目標文字串。 nmatch 是regmatch_t結構體陣列的長度。 matchptr regmatch_t型別的結構體陣列,存放匹配文字串的位置資訊。 eflags 有兩個值 REG_NOTBOL 按我的理解是如果指定了這個值,那麼'^'就不會從我們的目標串開始匹配。總之我到現在還不是很 明白這個引數的意義, 原文如下: If this bit is set, then the beginning-of-line operator doesn't match the beginning of the string (presumably because it's not the beginning of a line).If not set, then the beginning-of-line operator does match the beginning of the string. 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); 好了,下面來實戰一下,這樣你就會理解的更清楚了。 --------------------------------------------------------------- /* regex_test.c * regular expression test in GNU C * * tested on redhat6.1 * gcc regex_test.c -o regex_test */ #include #include #include #include #include #define SUBSLEN 10 #define EBUFLEN 128 /* error buffer length */ #define BUFLEN 1024 /* matched buffer length */ int main (int argc, char **argv) { FILE *fp; size_t len; /* store error message length */ regex_t re; /* store compilned regular expression */ regmatch_t subs[SUBSLEN]; /* store matched string position */ char matched[BUFLEN]; /* store matched strings */ char errbuf[EBUFLEN]; /* store error message */ int err, i; char string[] = "AAAAabaaababAbAbCdCd123123 11(123){12}"; char pattern[] = "(([0-9]+))({[0-9]+}{1})$"; printf ("String : %s
", string); printf ("Pattern: "%s"
", pattern); /* compile regular expression */ err = regcomp (&re, pattern, REG_EXTENDED); if (err) { len = regerror (err, &re, errbuf, sizeof (errbuf)); fprintf (stderr, "error: regcomp: %s
", errbuf); exit (1); } printf ("Total has subexpression: %d
", re.re_nsub); /* execute pattern match */ err = regexec (&re, string, (size_t)SUBSLEN, subs, 0); if (err == REG_NOMATCH) { fprintf (stderr, "Sorry, no match ...
"); regfree (&re); exit (0); } else if (err) { len = regerror (err, &re, errbuf, sizeof (errbuf)); fprintf (stderr, "error: regexec: %s
", errbuf); exit (1); } /* if no REG_NOMATCH and no error, then pattern matched */ printf ("
OK, has matched ...
"); for (i = 0; i <= re.re_nsub; i++) { if (i == 0) { printf ("begin: %d, end: %d, ", subs.rm_so, subs.rm_eo); } else { printf ("subexpression %d begin: %d, end: %d, ", i, subs.rm_so, subs.rm_eo); } len = subs.rm_eo - subs.rm_so; memcpy (matched, string + subs.rm_so, len); matched[len] = ''; printf ("match: %s
", matched); } regfree(&re); exit(0);
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8225414/viewspace-944546/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- C++與正規表示式入門C++
- 正規表示式入門
- JS正規表示式入門JS
- c# 正規表示式(轉)C#
- Regex 正規表示式入門
- 【記錄】正規表示式入門
- 正規表示式入門學習
- 正規表示式基礎入門
- C#快速入門教程(20)—— 字串與正規表示式C#字串
- 正規表示式從入門到入坑
- 從 例子 開始 入門 正則 表示式(-)
- 瞎說系列之正規表示式入門
- 正規表示式快速入門(歸納版)
- 正規表示式系列之初級入門篇
- javascript快速入門11--正規表示式JavaScript
- 正規表示式30分鐘入門教程
- 深入理解正規表示式:從入門到精通
- [轉]UltraEdit正規表示式
- C# 常用正規表示式C#
- lambda表示式——快速入門
- JS正規表示式從入門到入土(5)—— 量詞JS
- 爬蟲入門系列(六):正規表示式完全指南(下)爬蟲
- PHP入門:常量基本規則PHP
- python正規表示式 小例幾則Python
- 正規表示式 轉義字元字元
- 正規表示式語法(轉)
- 瞭解下C# 正規表示式C#
- GNU/linux的C函式庫介紹(轉)Linux函式
- re正規表示式庫的簡介、入門、使用方法
- JS正規表示式從入門到入土(10)—— 字串物件方法JS字串物件
- Linux系統程式設計(16)——正規表示式入門Linux程式設計
- c#表示式樹入門,看這個就夠了C#
- C#中幾個正規表示式匹配輸入字元的函式C#字元函式
- postgres中正規表示式及轉義
- 正規表示式使用詳解(轉)
- 常用有效的正規表示式【轉】
- 有shi以來最詳細的正規表示式入門教程
- 學習正規表示式(js、C#)JSC#