工作需要用到C++中的正則表達(dá)式,所以就研究了以上三種正則。
創(chuàng)新互聯(lián)建站于2013年成立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目網(wǎng)站設(shè)計制作、做網(wǎng)站網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元開福做網(wǎng)站,已為上家服務(wù),為開福各地企業(yè)和個人服務(wù),聯(lián)系電話:18982081108
/* write by xingming * time:2012年10月19日15:51:53 * for: test regex * */ #include #include #include #include #include #include using namespace std; const int times = 1000000; int main(int argc,char** argv) { char pattern[512]="finance\.sina\.cn|stock1\.sina\.cn|3g\.sina\.com\.cn.*(channel=finance|_finance$|ch=stock|/stock/)|dp.sina.cn/.*ch=9&"; const size_t nmatch = 10; regmatch_t pm[10]; int z ; regex_t reg; char lbuf[256]="set",rbuf[256]; char buf[3][256] = {"finance.sina.cn/google.com/baidu.com.google.sina.cndddddddddddddddddddddda.sdfasdfeoasdfnahsfonadsdf", "3g.com.sina.cn.google.com.dddddddddddddddddddddddddddddddddddddddddddddddddddddbaidu.com.sina.egooooooooo", "http://3g.sina.com.cn/google.baiduchannel=financegogo.sjdfaposif;lasdjf.asdofjas;dfjaiel.sdfaosidfj"}; printf("input strings:\n"); timeval end,start; gettimeofday(&start,NULL); regcomp(®,pattern,REG_EXTENDED|REG_NOSUB); for(int i = 0 ; i < times; ++i) { for(int j = 0 ; j < 3; ++j) { z = regexec(®,buf[j],nmatch,pm,REG_NOTBOL); /* if(z==REG_NOMATCH) printf("no match\n"); else printf("ok\n"); */ } } gettimeofday(&end,NULL); uint time = (end.tv_sec-start.tv_sec)*1000000 + end.tv_usec - start.tv_usec; cout<使用正則表達(dá)式可簡單的分成幾步: 1.編譯正則表達(dá)式 2.執(zhí)行匹配 3.釋放內(nèi)存 首先,編譯正則表達(dá)式int regcomp(regex_t *preg, const char *regex, int cflags);reqcomp()函數(shù)用于把正則表達(dá)式編譯成某種格式,可以使后面的匹配更有效。preg: regex_t結(jié)構(gòu)體用于存放編譯后的正則表達(dá)式;regex: 指向正則表達(dá)式指針;cflags:編譯模式共有如下四種編譯模式:REG_EXTENDED:使用功能更強(qiáng)大的擴(kuò)展正則表達(dá)式REG_ICASE:忽略大小寫REG_NOSUB:不用存儲匹配后的結(jié)果REG_NEWLINE:識別換行符,這樣‘$’就可以從行尾開始匹配,‘^’就可以從行的開頭開始匹配。否則忽略換行符,把整個文本串當(dāng)做一個字符串處理。其次,執(zhí)行匹配int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);preg: 已編譯的正則表達(dá)式指針;string:目標(biāo)字符串;nmatch:pmatch數(shù)組的長度;pmatch:結(jié)構(gòu)體數(shù)組,存放匹配文本串的位置信息;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) ***,釋放內(nèi)存void regfree(regex_t *preg);當(dāng)使用完編譯好的正則表達(dá)式后,或者需要重新編譯其他正則表達(dá)式時,一定要使用這個函數(shù)清空該變量。其他,處理錯誤size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);當(dāng)執(zhí)行regcomp 或者regexec 產(chǎn)生錯誤的時候,就可以調(diào)用這個函數(shù)而返回一個包含錯誤信息的字符串。errcode: 由regcomp 和 regexec 函數(shù)返回的錯誤代號。preg: 已經(jīng)用regcomp函數(shù)編譯好的正則表達(dá)式,這個值可以為NULL。errbuf: 指向用來存放錯誤信息的字符串的內(nèi)存空間。errbuf_size: 指明buffer的長度,如果這個錯誤信息的長度大于這個值,則regerror 函數(shù)會自動截斷超出的字符串,但他仍然會返回完整的字符串的長度。所以我們可以用如下的方法先得到錯誤字符串的長度。當(dāng)然我在測試的時候用到的也比較簡單,所以就直接用了,速度一會再說!2、C++ regex /* write by xingming * time:2012年10月19日15:51:53 * for: test regex * */ #include #include #include #include using namespace std; int main(int argc,char** argv) { regex pattern("[[:digit:]]",regex_constants::extended); printf("input strings:\n"); string buf; while(cin>>buf) { printf("*******\n%s\n********\n",buf.c_str()); if(buf == "quit") { printf("quit just now!\n"); break; } match_results result; printf("run compare now! '%s'\n", buf.c_str()); bool valid = regex_match(buf,result,pattern); printf("compare over now! '%s'\n", buf.c_str()); if(!valid) printf("no match!\n"); else printf("ok\n"); } return 0 ; }C++這個真心不想多說它,測試過程中發(fā)現(xiàn) 字符匹配的時候 ‘a(chǎn)’ 是可以匹配的,a+也是可以的,[[:w:]]也可以匹配任意字符,但[[:w:]]+就只能匹配一個字符,+號貌似不起作用了。所以后來就干脆放棄了這偉大的C++正則,如果有大牛知道這里面我錯在哪里了,真心感謝你告訴我一下,謝謝。3、boost regex /* write by xingming * for:test boost regex * time:2012年10月23日11:35:33 * */ #include #include #include #include "boost/regex.hpp" using namespace std; using namespace boost; const int times = 10000000; int main() { regex pattern("finance\\.sina\\.cn|stock1\\.sina\\.cn|3g\\.sina\\.com\\.cn.*(channel=finance|_finance$|ch=stock|/stock/)|dp\\.s ina\\.cn/.*ch=9&"); cout<<"input strings:"<boost正則不用多說了,要是出去問,C++正則怎么用???那90%的人會推薦你用boost正則,他實現(xiàn)起來方便,正則庫也很強(qiáng)大,資料可以找到很多,所以我也不在闡述了。4、對比情況總結(jié):C regex的速度讓我吃驚啊,相比boost的速度,C regex的速度幾乎要快上3倍,看來正則引擎的選取上應(yīng)該有著落了!上面的表格中我用到的正則和字符串是一樣的(在代碼中C regex的被我加長了),速度相差幾乎有3倍,C的速度大約在30+w/s , 而boost的速度基本在15-w/s ,所以對比就出來了!在這里Cregex的速度很讓我吃驚了已經(jīng),但隨后我的測試更讓我吃驚。我以前在.net正則方面接觸的比較多,就寫了一個.net版本的作為對比using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; namespace 平常測試 { class Program { static int times = 1000000; static void Main(string[] args) { Regex reg = new Regex(@"(?>finance\.sina\.cn|stock1\.sina\.cn|3g\.sina\.com\.cn.*(?:channel=finance|_finance$|ch=stock|/stock/)|dp.sina.cn/.*ch=9&)",RegexOptions.Compiled); string[] str = new string[]{@"finance.sina.cn/google.com/baidu.com.google.sina.cn", @"3g.com.sina.cn.google.com.baidu.com.sina.egooooooooo", @"http://3g.sina.com.cn/google.baiduchannel=financegogo"}; int tt = 0; DateTime start = DateTime.Now; for (int i = 0; i < times; ++i) { for (int j = 0; j < 3; ++j) { if (reg.IsMatch(str[j])) ; //Console.WriteLine("OK!"); //else //Console.WriteLine("Error!"); } } DateTime end = DateTime.Now; Console.WriteLine((end - start).TotalMilliseconds); Console.WriteLine(tt); Console.ReadKey(); } } }結(jié)果發(fā)現(xiàn),正則在不進(jìn)行RegexOptions.Compiled 的時候,速度和C regex的基本一樣,在編譯只會,速度會比C regex快上一倍,這不由得讓我對微軟的那群人的敬畏之情油然而生啊。但隨后我去查看了一下該博客上面C regex的描述,發(fā)現(xiàn)我可以再申明正則的時候加入編譯模式,隨后我加入了上面代碼里的 REG_NOSUB(在先前測試的時候是沒有加入的),結(jié)果讓我心理面很激動的速度出來了,C regex 匹配速度竟然達(dá)到了 300+w/s,也就是比原來的(不加入REG_NOSUB)的代碼快了將近10倍。之后我變換了匹配的字符串,將其長度生了一倍,達(dá)到每個100字符左右(代碼里面所示),匹配速度就下來了,但是也能達(dá)到 100w/s左右,這肯定滿足我們現(xiàn)在的需求了。結(jié)果很顯然,當(dāng)然會選擇C regex了。 文章標(biāo)題:C++中三種正則表達(dá)式比較 瀏覽地址:http://m.5511xx.com/article/cophggs.html
使用正則表達(dá)式可簡單的分成幾步:
首先,編譯正則表達(dá)式
int regcomp(regex_t *preg, const char *regex, int cflags);
reqcomp()函數(shù)用于把正則表達(dá)式編譯成某種格式,可以使后面的匹配更有效。
preg: regex_t結(jié)構(gòu)體用于存放編譯后的正則表達(dá)式;
regex: 指向正則表達(dá)式指針;
cflags:編譯模式
共有如下四種編譯模式:
REG_EXTENDED:使用功能更強(qiáng)大的擴(kuò)展正則表達(dá)式
REG_ICASE:忽略大小寫
REG_NOSUB:不用存儲匹配后的結(jié)果
REG_NEWLINE:識別換行符,這樣‘$’就可以從行尾開始匹配,‘^’就可以從行的開頭開始匹配。否則忽略換行符,把整個文本串當(dāng)做一個字符串處理。
其次,執(zhí)行匹配
int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
preg: 已編譯的正則表達(dá)式指針;
string:目標(biāo)字符串;
nmatch:pmatch數(shù)組的長度;
pmatch:結(jié)構(gòu)體數(shù)組,存放匹配文本串的位置信息;
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)
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)
***,釋放內(nèi)存
void regfree(regex_t *preg);
當(dāng)使用完編譯好的正則表達(dá)式后,或者需要重新編譯其他正則表達(dá)式時,一定要使用這個函數(shù)清空該變量。
其他,處理錯誤
size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);
當(dāng)執(zhí)行regcomp 或者regexec 產(chǎn)生錯誤的時候,就可以調(diào)用這個函數(shù)而返回一個包含錯誤信息的字符串。
errcode: 由regcomp 和 regexec 函數(shù)返回的錯誤代號。
preg: 已經(jīng)用regcomp函數(shù)編譯好的正則表達(dá)式,這個值可以為NULL。
errbuf: 指向用來存放錯誤信息的字符串的內(nèi)存空間。
errbuf_size: 指明buffer的長度,如果這個錯誤信息的長度大于這個值,則regerror 函數(shù)會自動截斷超出的字符串,但他仍然會返回完整的字符串的長度。所以我們可以用如下的方法先得到錯誤字符串的長度。
當(dāng)然我在測試的時候用到的也比較簡單,所以就直接用了,速度一會再說!
/* write by xingming * time:2012年10月19日15:51:53 * for: test regex * */ #include #include #include #include using namespace std; int main(int argc,char** argv) { regex pattern("[[:digit:]]",regex_constants::extended); printf("input strings:\n"); string buf; while(cin>>buf) { printf("*******\n%s\n********\n",buf.c_str()); if(buf == "quit") { printf("quit just now!\n"); break; } match_results result; printf("run compare now! '%s'\n", buf.c_str()); bool valid = regex_match(buf,result,pattern); printf("compare over now! '%s'\n", buf.c_str()); if(!valid) printf("no match!\n"); else printf("ok\n"); } return 0 ; }
C++這個真心不想多說它,測試過程中發(fā)現(xiàn) 字符匹配的時候 ‘a(chǎn)’ 是可以匹配的,a+也是可以的,[[:w:]]也可以匹配任意字符,但[[:w:]]+就只能匹配一個字符,+號貌似不起作用了。所以后來就干脆放棄了這偉大的C++正則,如果有大牛知道這里面我錯在哪里了,真心感謝你告訴我一下,謝謝。
/* write by xingming * for:test boost regex * time:2012年10月23日11:35:33 * */ #include #include #include #include "boost/regex.hpp" using namespace std; using namespace boost; const int times = 10000000; int main() { regex pattern("finance\\.sina\\.cn|stock1\\.sina\\.cn|3g\\.sina\\.com\\.cn.*(channel=finance|_finance$|ch=stock|/stock/)|dp\\.s ina\\.cn/.*ch=9&"); cout<<"input strings:"<boost正則不用多說了,要是出去問,C++正則怎么用???那90%的人會推薦你用boost正則,他實現(xiàn)起來方便,正則庫也很強(qiáng)大,資料可以找到很多,所以我也不在闡述了。4、對比情況總結(jié):C regex的速度讓我吃驚啊,相比boost的速度,C regex的速度幾乎要快上3倍,看來正則引擎的選取上應(yīng)該有著落了!上面的表格中我用到的正則和字符串是一樣的(在代碼中C regex的被我加長了),速度相差幾乎有3倍,C的速度大約在30+w/s , 而boost的速度基本在15-w/s ,所以對比就出來了!在這里Cregex的速度很讓我吃驚了已經(jīng),但隨后我的測試更讓我吃驚。我以前在.net正則方面接觸的比較多,就寫了一個.net版本的作為對比using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; namespace 平常測試 { class Program { static int times = 1000000; static void Main(string[] args) { Regex reg = new Regex(@"(?>finance\.sina\.cn|stock1\.sina\.cn|3g\.sina\.com\.cn.*(?:channel=finance|_finance$|ch=stock|/stock/)|dp.sina.cn/.*ch=9&)",RegexOptions.Compiled); string[] str = new string[]{@"finance.sina.cn/google.com/baidu.com.google.sina.cn", @"3g.com.sina.cn.google.com.baidu.com.sina.egooooooooo", @"http://3g.sina.com.cn/google.baiduchannel=financegogo"}; int tt = 0; DateTime start = DateTime.Now; for (int i = 0; i < times; ++i) { for (int j = 0; j < 3; ++j) { if (reg.IsMatch(str[j])) ; //Console.WriteLine("OK!"); //else //Console.WriteLine("Error!"); } } DateTime end = DateTime.Now; Console.WriteLine((end - start).TotalMilliseconds); Console.WriteLine(tt); Console.ReadKey(); } } }結(jié)果發(fā)現(xiàn),正則在不進(jìn)行RegexOptions.Compiled 的時候,速度和C regex的基本一樣,在編譯只會,速度會比C regex快上一倍,這不由得讓我對微軟的那群人的敬畏之情油然而生啊。但隨后我去查看了一下該博客上面C regex的描述,發(fā)現(xiàn)我可以再申明正則的時候加入編譯模式,隨后我加入了上面代碼里的 REG_NOSUB(在先前測試的時候是沒有加入的),結(jié)果讓我心理面很激動的速度出來了,C regex 匹配速度竟然達(dá)到了 300+w/s,也就是比原來的(不加入REG_NOSUB)的代碼快了將近10倍。之后我變換了匹配的字符串,將其長度生了一倍,達(dá)到每個100字符左右(代碼里面所示),匹配速度就下來了,但是也能達(dá)到 100w/s左右,這肯定滿足我們現(xiàn)在的需求了。結(jié)果很顯然,當(dāng)然會選擇C regex了。 文章標(biāo)題:C++中三種正則表達(dá)式比較 瀏覽地址:http://m.5511xx.com/article/cophggs.html
boost正則不用多說了,要是出去問,C++正則怎么用???那90%的人會推薦你用boost正則,他實現(xiàn)起來方便,正則庫也很強(qiáng)大,資料可以找到很多,所以我也不在闡述了。
C regex的速度讓我吃驚啊,相比boost的速度,C regex的速度幾乎要快上3倍,看來正則引擎的選取上應(yīng)該有著落了!
上面的表格中我用到的正則和字符串是一樣的(在代碼中C regex的被我加長了),速度相差幾乎有3倍,C的速度大約在30+w/s , 而boost的速度基本在15-w/s ,所以對比就出來了!
在這里Cregex的速度很讓我吃驚了已經(jīng),但隨后我的測試更讓我吃驚。
我以前在.net正則方面接觸的比較多,就寫了一個.net版本的作為對比
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; namespace 平常測試 { class Program { static int times = 1000000; static void Main(string[] args) { Regex reg = new Regex(@"(?>finance\.sina\.cn|stock1\.sina\.cn|3g\.sina\.com\.cn.*(?:channel=finance|_finance$|ch=stock|/stock/)|dp.sina.cn/.*ch=9&)",RegexOptions.Compiled); string[] str = new string[]{@"finance.sina.cn/google.com/baidu.com.google.sina.cn", @"3g.com.sina.cn.google.com.baidu.com.sina.egooooooooo", @"http://3g.sina.com.cn/google.baiduchannel=financegogo"}; int tt = 0; DateTime start = DateTime.Now; for (int i = 0; i < times; ++i) { for (int j = 0; j < 3; ++j) { if (reg.IsMatch(str[j])) ; //Console.WriteLine("OK!"); //else //Console.WriteLine("Error!"); } } DateTime end = DateTime.Now; Console.WriteLine((end - start).TotalMilliseconds); Console.WriteLine(tt); Console.ReadKey(); } } }
結(jié)果發(fā)現(xiàn),正則在不進(jìn)行RegexOptions.Compiled 的時候,速度和C regex的基本一樣,在編譯只會,速度會比C regex快上一倍,這不由得讓我對微軟的那群人的敬畏之情油然而生啊。
但隨后我去查看了一下該博客上面C regex的描述,發(fā)現(xiàn)我可以再申明正則的時候加入編譯模式,隨后我加入了上面代碼里的 REG_NOSUB(在先前測試的時候是沒有加入的),結(jié)果讓我心理面很激動的速度出來了,C regex 匹配速度竟然達(dá)到了 300+w/s,也就是比原來的(不加入REG_NOSUB)的代碼快了將近10倍。
之后我變換了匹配的字符串,將其長度生了一倍,達(dá)到每個100字符左右(代碼里面所示),匹配速度就下來了,但是也能達(dá)到 100w/s左右,這肯定滿足我們現(xiàn)在的需求了。
結(jié)果很顯然,當(dāng)然會選擇C regex了。
公司名稱:四川綿陽平武網(wǎng)站建設(shè)工作室 聯(lián)系電話:18980820575
網(wǎng)站備案號:蜀ICP備2024061352號-3
四川平武建站 四川平武網(wǎng)站建設(shè) 四川平武網(wǎng)站設(shè)計 四川平武網(wǎng)站制作 成都做網(wǎng)站