C++ 中三種正規表示式比較(C regex,C ++regex,boost regex)

發表於2016-12-28

工作需要用到C++中的正規表示式,所以就研究了以上三種正則。

1,C regex

使用正規表示式可簡單的分成幾步:

1.編譯正規表示式

2.執行匹配

3.釋放記憶體

首先,編譯正規表示式

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

reqcomp()函式用於把正規表示式編譯成某種格式,可以使後面的匹配更有效。

preg: regex_t結構體用於存放編譯後的正規表示式;

regex: 指向正規表示式指標;

cflags:編譯模式

共有如下四種編譯模式:

REG_EXTENDED:使用功能更強大的擴充套件正規表示式

REG_ICASE:忽略大小寫

REG_NOSUB:不用儲存匹配後的結果

REG_NEWLINE:識別換行符,這樣‘$’就可以從行尾開始匹配,‘^’就可以從行的開頭開始匹配。否則忽略換行符,把整個文字串當做一個字串處理。

其次,執行匹配

int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);

preg: 已編譯的正規表示式指標;

string:目標字串;

nmatch:pmatch陣列的長度;

pmatch:結構體陣列,存放匹配文字串的位置資訊;

eflags:匹配模式

共兩種匹配模式:

REG_NOTBOL:The match-beginning-of-line operator always fails to match  (but see  the  compilation  flag  REG_NEWLINE above). This flag may be used when different portions of a string are passed  to  regexec and the beginning of the string should not be interpreted as the beginning of the line.

REG_NOTEOL:The match-end-of-line operator always fails to  match  (but  see the compilation flag REG_NEWLINE above)

最後,釋放記憶體

void regfree(regex_t *preg);

當使用完編譯好的正規表示式後,或者需要重新編譯其他正規表示式時,一定要使用這個函式清空該變數。

其他,處理錯誤

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

當執行regcomp 或者regexec 產生錯誤的時候,就可以呼叫這個函式而返回一個包含錯誤資訊的字串。

errcode: 由regcomp 和 regexec 函式返回的錯誤代號。

preg: 已經用regcomp函式編譯好的正規表示式,這個值可以為NULL。

errbuf: 指向用來存放錯誤資訊的字串的記憶體空間。

errbuf_size: 指明buffer的長度,如果這個錯誤資訊的長度大於這個值,則regerror 函式會自動截斷超出的字串,但他仍然會返回完整的字串的長度。所以我們可以用如下的方法先得到錯誤字串的長度。

當然我在測試的時候用到的也比較簡單,所以就直接用了,速度一會再說!

2,C++ regex

C++這個真心不想多說它,測試過程中發現 字元匹配的時候 ‘a’ 是可以匹配的,a+也是可以的,[[:w:]]也可以匹配任意字元,但[[:w:]]+就只能匹配一個字元,+號貌似不起作用了。所以後來就乾脆放棄了這偉大的C++正則,如果有大牛知道這裡面我錯在哪裡了,真心感謝你告訴我一下,謝謝。

3,boost regex

boost正則不用多說了,要是出去問,C++正則怎麼用啊?那90%的人會推薦你用boost正則,他實現起來方便,正則庫也很強大,資料可以找到很多,所以我也不在闡述了。

4,對比情況

%e5%8e%bb%e5%8e%bb%e5%8e%bb

總結:

C regex的速度讓我吃驚啊,相比boost的速度,C regex的速度幾乎要快上3倍,看來正則引擎的選取上應該有著落了!

上面的表格中我用到的正則和字串是一樣的(在程式碼中C regex的被我加長了),速度相差幾乎有3倍,C的速度大約在30+w/s , 而boost的速度基本在15-w/s ,所以對比就出來了!

在這裡Cregex的速度很讓我吃驚了已經,但隨後我的測試更讓我吃驚。

我以前在.net正則方面接觸的比較多,就寫了一個.net版本的作為對比,

結果發現,正則在不進行RegexOptions.Compiled 的時候,速度和C regex的基本一樣,在編譯只會,速度會比C regex快上一倍,這不由得讓我對微軟的那群人的敬畏之情油然而生啊。

但隨後我去檢視了一下該部落格上面C regex的描述,發現我可以再申明正則的時候加入編譯模式,隨後我加入了上面程式碼裡的 REG_NOSUB(在先前測試的時候是沒有加入的),結果讓我心理面很激動的速度出來了,C regex 匹配速度竟然達到了 300+w/s,也就是比原來的(不加入REG_NOSUB)的程式碼快了將近10倍。

之後我變換了匹配的字串,將其長度生了一倍,達到每個100字元左右(程式碼裡面所示),匹配速度就下來了,但是也能達到 100w/s左右,這肯定滿足我們現在的需求了。

結果很顯然,當然會選擇C regex了。

相關文章