天天看點

RE2、glibc regex 和 C++ regex 正則庫的使用和對比一、RE2二、glibc regex三、C++ regex四、對比情況五、參考資料

一、RE2

RE2

是 google 開源的正規表達式庫,由

Rob Pike

Russ Cox

兩位來自 google 的大牛用 C++ 實作。

它快速、安全,線程友好,是

PCRE

PERL

Python

等回溯正規表達式引擎(backtracking regular expression engine)的一個替代品。RE2 支援 Linux 和絕大多數的 Unix 平台。

簡單使用方法如下:

#include <iostream>
#include <re2/re2.h>
#include <re2/set.h>

int main()
{
    // 也可以使用 re2_->Match() 直接比對,我這裡是将正則式加入到集合裡
    RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);
    s.Add("food", NULL);
    s.Add("bar", NULL);

    s.Compile();  // 編譯
    bool isMatch = s.Match("foobar", NULL);  // 比對字元串

    std::cout << isMatch << std::endl;
    return ;
}
           

二、glibc regex

GNU C 庫支援兩種正規表達式比對接口。一個是

POSIX.2

标準接口,另一個就是

GNU C

庫中已經存在很多年的接口了。

兩種接口的聲明都在頭檔案

regex.h

中。如果你定義

_POSIX_C_SOURCE

,那麼隻能用 POSIX.2 的函數、結構和常量以及聲明。

// 将正則式編譯成 regexec 使用的形式,preg 存儲 regex 編譯後的結果
int regcomp(regex_t *preg, const char *regex, int cflags);

// 比對非空字元串和預編譯好的正則式
int regexec(const regex_t *preg, const char *string, size_t nmatch,
                regmatch_t pmatch[], int eflags);

// 如果有錯誤發生,根據 errcode 得到相應的錯誤描述
size_t regerror(int errcode, const regex_t *preg, char *errbuf,
                    size_t errbuf_size);

// 釋放預編譯正則式的 buffer
void regfree(regex_t *preg);
           

簡單使用方法如下:

#include <stdio.h>
#include <sys/types.h>
#include <regex.h>

int match(const char *str, const char *pattern)
{
    regex_t re;
    int err;

    err = regcomp(&re, pattern, REG_EXTENDED);
    if (err != ) {
        char buf[];
        regerror(err, &re, buf, sizeof(buf));
        printf("FAIL: %s\n", buf);
        return ;
    }

    err = regexec(&re, str, , NULL, );
    regfree(&re);

    if (err)
        return ;
    return ;
}

int main(void)
{
    const char *reg = "[a-c][e-f]";
    const char *str = "abcef";

    int ret = match(str, reg);
    printf("ret = %d\n", ret);

    return ;
}
           

三、C++ regex

标準 c++ 庫也提供支援正規表達式的

<regex>

頭來實作類似上面的的操作。

簡單使用方法如下:

#include <iostream>
#include <string>
#include <regex>

int main()
{
    std::string s("subject");
    std::regex e("sub");
    bool isMatch = std::regex_match(s, e);  // 比對
    std::cout << isMatch << std::endl;
    return ;
}
           

四、對比情況

  • RE2-20160401
  • glibc-2.23
  • 标準 C++ 庫,C++ 11

測試資料是提前準備好的一個正規表達式的清單和一些待比對的字元串。

P.S. 以下對比無圖無真相

gcc 版本支援情況

RE2 和 glibc 的 regex 都沒問題,C++ 的

<regex>

隻有在 gcc 4.8.5 上能正常使用,在 gcc 4.4.1 以及 gcc 4.4.7 上都編譯不過去,報錯如下:

undefined reference to `std::basic_regex<char, std::regex_traits<char> >::_M_compile()
           

由于線上的環境是 gcc 4.4.7 的,是以 C++ 的就被我排除掉了,下面的對比隻涉及 RE2 和 glibc 的正則庫。

記憶體占用情況

實際使用中,glibc regex > RE2

CPU 使用率情況

glibc regex > RE2

其他庫對比情況

網上有 RE2、TRE 和 PCRE 等正則庫的對比,我這裡木有實際測試。

–> 正則對比 - 傳送門 <–

P.S. 我自測中,glibc regex 比 boost 中的正則庫快很多。

五、參考資料

RE2

glibc regex

C++ regex

Regular Expressions (C++) 文法

繼續閱讀