1

我正在寻找一个 C/C++ 中的正则表达式库,它不提供通用 API regex(string, pattern),而是允许构造一个有限状态机(基于模式),我只想调用

fsm = create_fsm();
add_pattern(fsm, "foo", hookFoo);
add_pattern(fsm, "bar", hookBar);
compile_fsm(fsm);
while ((c = fgetc(file) != EOF) {
   next_char(fsm, c);
}

如果模式匹配,hookFoo(match start, match end) 会被调用吗?或类似的东西,这只是概念。我想在很长很长的行中搜索多个正则表达式。理想情况下,如果它也可以反向填充以进行向后搜索。由于表达式仅在运行时已知,Flex(或类似的解析器生成器)不是一个选项。

编辑: 虽然我已将 lexertl 标记为正确答案,但它似乎不是我想要的。它需要返回流;我不想使用内存来记住过去(除了恒定大小,例如记住最后一个字符)。想象一下,当我调用 ++iterator 时,所有其他迭代器都应该失效。

4

4 回答 4

2

看起来lexertl对您的要求有很长的路要走。它支持在运行时添加正则表达式和“可重新启动”词法分析器。它会为每个公认的“规则”给你一个令牌。

boost::spirit::lex使用 lexertl 作为默认实现,它添加了语义操作。

于 2013-01-09T15:18:01.287 回答
1

#include<regex.h>您可以使用like提供的函数开发自己的函数regcomp,并且regexec

例子

int  match_patterns(char *pch,char *pattern)
{
    regex_t             *regex;
    regmatch_t          *result;
    int                 err_no = 0;
    int                 start = 0;

    regex = (regex_t *) calloc(1,sizeof(regex_t));
    if((err_no = regcomp(regex, pattern, REG_EXTENDED)) != 0)
    {
        size_t          length;
        char            *buffer;
        length = regerror (err_no, regex, NULL, 0);
        buffer = malloc(length);
        regerror (err_no, regex, buffer, length);
        free(buffer);
        regfree(regex);
        return -1; //error
    }
    result = (regmatch_t *) calloc(1,sizeof(regmatch_t));
    if(result == NULL)
    {
        return -1; //error
    }
    while(regexec(regex, pch+start, 1, result, 0) == 0)
    {
        start +=result->rm_eo;
    }
    regfree(regex);
    free(regex);
    if((result->rm_so == 0)&&(result->rm_eo == strlen(pch)))
    {
        return 0; //OK
    }
    return -1; //error
}

pch如果字符串与正则表达式模式匹配,此函数将返回 0,pattern否则返回 -1。

例子

int main()
{
    if (match_patterns("1234.abc", "[0-9]+.[a-d]+")==0)
        printf("OK!\n");
    else
        printf("NOK!\n");

}

match_patterns()这种情况下将返回 0

如果您使用此功能,请不要忘记添加以下 iclude:

#include<regex.h>
#include<string.h>
于 2013-01-09T15:10:08.847 回答
1

有来自 Intel 的 hyperscan 库。它提供了 api 来搜索数据流中的多个正则表达式。请参阅http://intel.github.io/hyperscan/dev-reference/runtime.html#streaming-mode

于 2021-04-06T20:43:37.777 回答
0

经过一番谷歌搜索后,我发现了 RE2 库http://code.google.com/p/re2/ - 这表明它是一种快速的实现(速度与 grep 或 awk 相当),并在背景中有正确的理论并且可以提供内存限制。RE2::FindAndConsume 似乎是正确的 API。

编辑:不(再次)。FindAndConsume 只在一个字符串中找到增量匹配,但不允许传递数据流的多个块 :( 顺便说一下,当找到匹配时,机器会返回查看匹配实际开始的位置(尽管这不是那么大问题,因为它不应该在前向搜索期间这样做,例如lexertl所做的。

于 2013-01-18T22:15:30.407 回答