天天看点

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++) 语法

继续阅读