linux c 語言中使用正規表示式pcre

2021-04-28 06:22:08 字數 4123 閱讀 3527

說起正規表示式(regular expression),也許有的朋友天天都在使用,比如grep、vim、sed、awk,只是可能對這個名詞不大熟悉。正規表示式一般簡寫為regex或者regexp,甚至是re。關於正規表示式的介紹,有很多的文章,用搜尋引擎查詢就可以找到很不錯的使用說明。但是在c/c++語言中如何去使用,相應的介紹比較缺乏。大多數c標準庫自帶regex,可以通過/usr/include/regex.h去看,或者man regex看使用說明。perl,php等語言更是提供了功能強大的正規表示式,最著名的c語言正規表示式庫為pcre(perl compatible regular expression)。本文主要對regex和pcre的使用做一點入門介紹。

1、regex

code:

#include

#include

#include

#define subslen 10              /* 匹配子串的數量 */

#define ebuflen 128             /* 錯誤訊息buffer長度 */

#define buflen 1024             /* 匹配到的字串buffer長度 */

int main()

printf("total has subexpression: %d/n", re.re_nsub);

/* 執行模式匹配 */

err = regexec(&re, src, (size_t) subslen, subs, 0);

if (err == reg_nomatch) else if (err)

/* 如果不是reg_nomatch並且沒有其它錯誤,則模式匹配上 */

printf("/nok, has matched .../n/n");

for (i = 0; i <= re.re_nsub; i++) else

memcpy (matched, src + subs[i].rm_so, len);

matched[len] = '/0';

printf("match: %s/n", matched);

}regfree(&re);   /* 用完了別忘了釋放 */

return (0);

}執行結果是

code:

string : 111 hello world 222

pattern: "(.*)"

total has subexpression: 1

ok, has matched ...

begin: %, len = 4  match: hello world

subexpression 1 begin: 11, len = 11  match: hello world從示例程式可以看出,使用之前先用regcomp()編譯一下,然後呼叫regexec()進行實際匹配。如果只是看有沒有匹配成功,掌握這2個函式的用法即可。有時候我們想要取得匹配後的子表示式,比如示例中想獲得title是什麼,需要用小括號 "( )"把子表示式括起來"(.*)",表示式引擎會將小括號 "( )" 包含的表示式所匹配到的字串記錄下來。在獲取匹配結果的時候,小括號包含的表示式所匹配到的字串可以單獨獲取,示例程式就是我用來獲取http網頁的主題(title)的方式。  

regmatch_t subs[subslen]是用來存放匹配位置的,subs[0]裡存放這個匹配的字串位置,subs[1]裡存放第乙個子表示式的匹配位置,也就是例子中的title,通過結構裡的rm_so和rm_eo可以取到,這一點很多人不太注意,應該強調一下。

注釋1:開始除錯**的時候是在freebsd 6.2上進行的,print出來的len總是0,但print出來的字串又沒錯,很是迷惑,把它放到linux上則完全正常,後來仔細檢查才發現rm_so在linux上是32位,在freebsd上是64位,用%d的話實際取的是rm_so的高32位,而不是實際的len,把print rm_so的地方改為%llu就可以了。

regex雖然簡單易用,但對正規表示式的支援不夠強大,中文處理也有問題,於是引出了下面要說的pcre。

pcre的名字就說明了是perl compatible,熟悉perl、php的人使用起來完全沒有問題。pcre有非常豐富的使用說明和示例**(看看pcredemo.c就能明白基本的用法),下面的程式只是把上面regex改為pcre。

code:

/* compile thuswise:   

*   gcc -wall pcre1.c -i/usr/local/include -l/usr/local/lib -r/usr/local/lib -lpcre

*      

*/     

#include

#include

#include

#define oveccount 30    /* should be a multiple of 3 */

#define ebuflen 128            

#define buflen 1024           

int main()

rc = pcre_exec(re, null, src, strlen(src), 0, 0, ovector, oveccount);

if (rc < 0)

printf("/nok, has matched .../n/n");

for (i = 0; i < rc; i++)

free(re);

return 0;

}執行結果是:

code:

string : 111 hello world 222

pattern: "(.*)"

ok, has matched ...

0: hello world

1: hello world比較這2個例子可以看出,在regex用的是regcomp()、regexec(),pcre則使用pcre_compile()、pcre_exec(),用法幾乎完全一致。

pcre_compile()有很多選項,詳細說明參見

。如果是多行文字,可以設定pcre_dotall的選項pcre_complie(re, pcre_dotall,....),表示'.'也匹配回車換行"/r/n"。

)對pcre做了c++封裝,使用起來更加方便。

code:

/*

* g++ pcre2.cpp -i/usr/local/include -l/usr/local/lib -r/usr/local/lib -lpcre++ -lpcre

*/#include

#include

#include

using namespace std;

using namespace pcrepp;

int main()

} else

return 0;

}執行結果是:

code:

string : 111 hello world 222

pattern : (.*)

ok, has matched ...

0: hello world4、oniguruma

還有乙個正規表示式的庫oniguruma(

),對於東亞文字支援比較好,開始是用在ruby上,也可用於c++,是日本的開發人員編寫的。大多數人都不會用到,也就不做介紹了。如果有疑問可以通過email來討論它的用法。

5、regular expression的內部實現

關於regular expression的實現,用到了不少自動機理論(automata theory)的知識,有興趣的可以找這方面的資料來看,這本書「 introduction to automata theory, languages, and computation」寫的很好,編譯原理的書也有這方面的內容。

C語言中使用正規表示式

有四個函式 int regcomp regex t compiled,const char pattern,int cflags 引數1 結構體 編譯 字串 結構體 儲存正規表示式 引數2 正規表示式串。引數3 標誌位 1.擴充套件正則 reg extended 2.忽略大小寫 reg icase ...

在C C 語言中使用正規表示式

說起正規表示式 regular expression 也許有的朋友天天都在使用,比如grep vim sed awk,只是可能對這個名詞不大熟悉。正規表示式一般簡寫為regex或者regexp,甚至是re。關於 正規表示式的介紹,有很多的文章,用搜尋引擎查詢就可以找到很不錯的使用說明。但是在c c ...

在linux C中使用正規表示式pcre

原 2018年04月15日 16 41 44 更多個人分類 linux c高階程式設計 程式示例 include include include define oveccount 3000 define ebuflen 128 define buflen 1024 int main for prin...