繁体   English   中英

建议 C 正则表达式扫描器(流阅读器)

[英]Suggest C regex scanner (stream reader)

我正在寻找 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 时,所有其他迭代器都应该无效。

看起来lexertl对您的要求大有帮助 它支持在运行时添加正则表达式和“可重启”词法分析器。 它将为每个公认的“规则”提供一个标记。

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

您可以使用#include<regex.h>提供的函数(如regcompregexec开发自己的函数

例子

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
}

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

例子

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

}

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM