偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

C++中三種正則表達(dá)式比較

開發(fā) 后端
之后我變換了匹配的字符串,將其長(zhǎng)度生了一倍,達(dá)到每個(gè)100字符左右(代碼里面所示),匹配速度就下來了,但是也能達(dá)到 100w/s左右,這肯定滿足我們現(xiàn)在的需求了。

工作需要用到C++中的正則表達(dá)式,所以就研究了以上三種正則。

1、C regex

/*  write by xingming  *  time:2012年10月19日15:51:53  *  for: test regex  *  */

#include <regex.h>
#include <iostream>
#include <sys/types.h>
#include <stdio.h>
#include <cstring>
#include <sys/time.h>

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(&reg,pattern,REG_EXTENDED|REG_NOSUB);
    for(int i = 0 ; i < times; ++i)
    {
        for(int j = 0 ; j < 3; ++j)
        {
            z = regexec(&reg,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<<time/1000000<<" s and "<<time%1000000<<" us."<<endl;
    return 0 ;
}

使用正則表達(dá)式可簡(jiǎn)單的分成幾步:

  • 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:不用存儲(chǔ)匹配后的結(jié)果

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

其次,執(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ù)組的長(zhǎng)度;

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í),一定要使用這個(gè)函數(shù)清空該變量。

其他,處理錯(cuò)誤

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

當(dāng)執(zhí)行regcomp 或者regexec 產(chǎn)生錯(cuò)誤的時(shí)候,就可以調(diào)用這個(gè)函數(shù)而返回一個(gè)包含錯(cuò)誤信息的字符串。

errcode: 由regcomp 和 regexec 函數(shù)返回的錯(cuò)誤代號(hào)。

preg: 已經(jīng)用regcomp函數(shù)編譯好的正則表達(dá)式,這個(gè)值可以為NULL。

errbuf: 指向用來存放錯(cuò)誤信息的字符串的內(nèi)存空間。

errbuf_size: 指明buffer的長(zhǎng)度,如果這個(gè)錯(cuò)誤信息的長(zhǎng)度大于這個(gè)值,則regerror 函數(shù)會(huì)自動(dòng)截?cái)喑龅淖址?,但他仍然?huì)返回完整的字符串的長(zhǎng)度。所以我們可以用如下的方法先得到錯(cuò)誤字符串的長(zhǎng)度。

當(dāng)然我在測(cè)試的時(shí)候用到的也比較簡(jiǎn)單,所以就直接用了,速度一會(huì)再說!

2、C++ regex

/*  write by xingming  *  time:2012年10月19日15:51:53  *  for: test regex  *  */

#include <regex>
#include <iostream>
#include <stdio.h>
#include <string>

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<string::const_iterator> 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++這個(gè)真心不想多說它,測(cè)試過程中發(fā)現(xiàn) 字符匹配的時(shí)候 ‘a’ 是可以匹配的,a+也是可以的,[[:w:]]也可以匹配任意字符,但[[:w:]]+就只能匹配一個(gè)字符,+號(hào)貌似不起作用了。所以后來就干脆放棄了這偉大的C++正則,如果有大牛知道這里面我錯(cuò)在哪里了,真心感謝你告訴我一下,謝謝。

3、boost regex

/* write by xingming
 * for:test boost regex
 * time:2012102311:35:33
 * */  #include <iostream> #include <string> #include <sys/time.h>
#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:"<<endl;
    timeval start,end;
    gettimeofday(&start,NULL);
    string input[] = {"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"};
    for(int i = 0 ;i < times; ++ i)
    {
        for(int j = 0 ; j < 3;++j)
        {
            //if(input=="quit")
            //  break;
            //cout<<"string:'"<<input<<'\''<<endl;
            cmatch what;
            if(regex_search(input[j].c_str(),what,pattern)) ;
            //  cout<<"OK!"<<endl;
            else ;
            //  cout<<"error!"<<endl;
        }
    }
    gettimeofday(&end,NULL);
    uint time = (end.tv_sec-start.tv_sec)*1000000 + end.tv_usec - start.tv_usec;
    cout<<time/1000000<<" s and "<<time%1000000<<" us."<<endl;
    return 0 ;
}

boost正則不用多說了,要是出去問,C++正則怎么用???那90%的人會(huì)推薦你用boost正則,他實(shí)現(xiàn)起來方便,正則庫(kù)也很強(qiáng)大,資料可以找到很多,所以我也不在闡述了。

4、對(duì)比情況

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

總結(jié):

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

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

在這里Cregex的速度很讓我吃驚了已經(jīng),但隨后我的測(cè)試更讓我吃驚。

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace 平常測(cè)試
{
    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 的時(shí)候,速度和C regex的基本一樣,在編譯只會(huì),速度會(huì)比C regex快上一倍,這不由得讓我對(duì)微軟的那群人的敬畏之情油然而生啊。

但隨后我去查看了一下該博客上面C regex的描述,發(fā)現(xiàn)我可以再申明正則的時(shí)候加入編譯模式,隨后我加入了上面代碼里的 REG_NOSUB(在先前測(cè)試的時(shí)候是沒有加入的),結(jié)果讓我心理面很激動(dòng)的速度出來了,C regex 匹配速度竟然達(dá)到了 300+w/s,也就是比原來的(不加入REG_NOSUB)的代碼快了將近10倍。

之后我變換了匹配的字符串,將其長(zhǎng)度生了一倍,達(dá)到每個(gè)100字符左右(代碼里面所示),匹配速度就下來了,但是也能達(dá)到 100w/s左右,這肯定滿足我們現(xiàn)在的需求了。

結(jié)果很顯然,當(dāng)然會(huì)選擇C regex了。

責(zé)任編輯:張燕妮 來源: pmars的博客
相關(guān)推薦

2010-07-14 09:24:22

Perl正則表達(dá)式

2010-07-19 16:11:20

Perl正則表達(dá)式

2009-08-17 13:56:28

C#正則表達(dá)式入門

2009-08-07 15:16:10

C#正則表達(dá)式

2009-08-03 17:27:14

C#正則表達(dá)式

2020-09-04 09:16:04

Python正則表達(dá)式虛擬機(jī)

2018-09-27 15:25:08

正則表達(dá)式前端

2009-08-13 15:24:27

C#正則表達(dá)式

2009-08-11 13:00:41

C#正則表達(dá)式

2010-03-03 12:53:50

Linux正則表達(dá)式

2024-12-16 07:33:45

C#正則表達(dá)式

2024-09-14 09:18:14

Python正則表達(dá)式

2022-01-04 11:35:03

Linux Shel正則表達(dá)式Linux

2016-11-10 16:21:22

Java 正則表達(dá)式

2009-09-16 17:15:57

正則表達(dá)式引擎

2023-09-13 08:12:45

2009-08-14 15:50:45

C#正則表達(dá)式

2009-08-20 15:10:33

C#正則表達(dá)式

2009-08-20 15:06:51

C#正則表達(dá)式

2009-08-13 15:02:52

C#正則表達(dá)式引擎貪婪
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)