一、簡介
一個好的程序員是會使用DB和Regular Expression的程序員,可見兩者是多么重要。正則表達式是能極大地提高工作效率的工具,使用過Linux下各種具備RE特性的工具的人一定對此深有感觸。很多語言都支持RE,用的最多的當然是腳本,其中以perl最盛。不過,用C語言來用RE不是很多見,但是有時候也很有用,我最近也是看到別人說道這個,所以搜了一些資料加上自己的體會來說一說RE在C語言里的應用。C語言本身不具備RE特性,但是有很多庫,在Linux下你可以很方便的使用regex.h提供的庫。
二、API
http://blog.chinaunix.net/uid-479984-id-2114941.html
http://blog.sina.com.cn/s/blog_6a1837e901010ckv.html
http://blog.chinaunix.net/uid-17240700-id-2813921.html
三、實例
示例1:example1.c
#include<stdio.h> #include<sys/types.h> #include<regex.h> #include<memory.h> #include<stdlib.h> int main(){ char *bematch = "hhhericchd@gmail.com"; char *pattern = "h{3,10}(.*)@.{5}.(.*)"; char errbuf[1024]; char match[100]; regex_t reg; int err,nm = 10; regmatch_t pmatch[nm]; if(regcomp(®,pattern,REG_EXTENDED) < 0){ regerror(err,®,errbuf,sizeof(errbuf)); printf("err:%s\n",errbuf); } err = regexec(®,bematch,nm,pmatch,0); if(err == REG_NOMATCH){ printf("no match\n"); exit(-1); }else if(err){ regerror(err,®,errbuf,sizeof(errbuf)); printf("err:%s\n",errbuf); exit(-1); } for(int i=0;i<10 && pmatch[i].rm_so!=-1;i++){ int len = pmatch[i].rm_eo-pmatch[i].rm_so; if(len){ memset(match,'\0',sizeof(match)); memcpy(match,bematch+pmatch[i].rm_so,len); printf("%s\n",match); } } return 0; }
編譯
gcc -g -o example1 example1.c --std=c99
運行
示例2:example2.c
#define PCRE_STATIC // 靜態庫編譯選項 #include <stdio.h> #include <string.h> #include <pcre.h> #define OVECCOUNT 30 #define EBUFLEN 128 #define BUFLEN 1024 int main () { pcre *re; const char *error; int erroffset; int ovector[OVECCOUNT]; int rc, i; char src[] = "111 <title>Hello World</title> 222"; // 要被用來匹配的字符串 char pattern[] = "<title>(.*)</(tit)le>"; // 將要被編譯的字符串形式的正則表達式 printf ("String : %s\n", src); printf ("Pattern: \"%s\"\n", pattern); re = pcre_compile (pattern, // pattern, 輸入參數,將要被編譯的字符串形式的正則表達式 0, // options, 輸入參數,用來指定編譯時的一些選項 &error, // errptr, 輸出參數,用來輸出錯誤信息 &erroffset, // erroffset, 輸出參數,pattern中出錯位置的偏移量 NULL); // tableptr, 輸入參數,用來指定字符表,一般情況用NULL // 返回值:被編譯好的正則表達式的pcre內部表示結構 if (re == NULL) { //如果編譯失敗,返回錯誤信息 printf ("PCRE compilation failed at offset %d: %s\n", erroffset, error); return 1; } rc = pcre_exec (re, // code, 輸入參數,用pcre_compile編譯好的正則表達結構的指針 NULL, // extra, 輸入參數,用來向pcre_exec傳一些額外的數據信息的結構的指針 src, // subject, 輸入參數,要被用來匹配的字符串 strlen (src), // length, 輸入參數,要被用來匹配的字符串的指針 0, // startoffset, 輸入參數,用來指定subject從什么位置開始被匹配的偏移量 0, // options, 輸入參數,用來指定匹配過程中的一些選項 ovector, // ovector, 輸出參數,用來返回匹配位置偏移量的數組 OVECCOUNT); // ovecsize, 輸入參數, 用來返回匹配位置偏移量的數組的最大大小 // 返回值:匹配成功返回非負數,沒有匹配返回負數 if (rc < 0) { //如果沒有匹配,返回錯誤信息 if (rc == PCRE_ERROR_NOMATCH) printf ("Sorry, no match ...\n"); else printf ("Matching error %d\n", rc); pcre_free (re); return 1; } printf ("\nOK, has matched ...\n\n"); //沒有出錯,已經匹配 for (i = 0; i < rc; i++) { //分別取出捕獲分組 $0整個正則公式 $1第一個() char *substring_start = src + ovector[2 * i]; int substring_length = ovector[2 * i + 1] - ovector[2 * i]; printf ("$-: %d,%d,%s\n", i, substring_length, substring_start); } pcre_free (re); // 編譯正則表達式re 釋放內存 return 0; }
編譯
gcc -g -o example2 example2.c -lpcre
運行