C++ 建议使用C正则表达式扫描仪(流读取器)

C++ 建议使用C正则表达式扫描仪(流读取器),c++,c,regex,parsing,C++,C,Regex,Parsing,我正在寻找C/C++中的正则表达式库,它不提供公共API正则表达式(字符串、模式),而是允许构造有限状态机(基于模式),我只需调用 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(匹

我正在寻找C/C++中的正则表达式库,它不提供公共API正则表达式(字符串、模式),而是允许构造有限状态机(基于模式),我只需调用

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(匹配开始,匹配结束)? 或者类似的,这只是一个概念。我想搜索长行中的多个regexp。理想情况下,如果它也可以在反向填充以进行反向搜索。 因为表达式只在运行时才知道,所以Flex(或类似的解析器生成器)不是一个选项

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

您可以使用
\include
提供的函数开发自己的函数,如
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
}
int main()
{
    if (match_patterns("1234.abc", "[0-9]+.[a-d]+")==0)
        printf("OK!\n");
    else
        printf("NOK!\n");

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

范例

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
}
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>
#包括
#包括

您可以使用
\include
提供的函数开发自己的函数,如
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
}
int main()
{
    if (match_patterns("1234.abc", "[0-9]+.[a-d]+")==0)
        printf("OK!\n");
    else
        printf("NOK!\n");

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

范例

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
}
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>
#包括
#包括
它看起来离您的需求还有很长的路要走。它既支持在运行时添加正则表达式,也支持“可重启”lexer。它将为每个已识别的“规则”提供一个令牌

使用lexertl作为默认实现,并添加语义操作。

它看起来离您的需求还有很长的路要走。它既支持在运行时添加正则表达式,也支持“可重启”lexer。它将为每个已识别的“规则”提供一个令牌


使用lexertl作为默认实现,并添加语义操作。

在谷歌搜索了更多的内容后,我发现了RE2库-这是一个快速的实现(速度相当于grep或awk),具有正确的背景理论,可以提供内存限制。 RE2::FindAndConsume似乎是正确的API


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

在更多的谷歌搜索之后,我发现了RE2库-这是一个快速的实现(速度相当于grep或awk),在后台有正确的理论,并且可以提供内存限制。 RE2::FindAndConsume似乎是正确的API


编辑:否(再次)。FindAndConsume仅在一个字符串中查找增量匹配,但不允许传递多个数据流块:(顺便说一句,当找到匹配时,机器将返回以查看匹配的实际开始位置(虽然这不是一个大问题,因为它不应该在正向搜索过程中这样做,例如,lexertl

有Intel提供的hyperscan库。它提供了在数据流中搜索多个正则表达式的api。请参阅有Intel提供的hyperscan库。它提供了搜索多个正则表达式的api。)在数据流中,请参见“/p>”,因为你好奇,你在C/C++中需要一个。你知道另一种语言吗?有一个迭代器你可以扩展并实现PEG-使用语言工作台导出你的解析树。AK479:不,我刚刚指定了这个,因为我想在C++应用程序中使用它。但是如果你知道任何这样的库Java扫描器可以使用(因为它接受流)虽然不是很有吸引力,但出于好奇,你需要一个C/C++。你知道一个迭代器可以扩展和实现PEG-使用语言工作台导出你的解析树。AK479:不,我刚刚指定了这个,因为我想在C++应用程序中使用它。但是如果你知道在DIFI中有这样的库。语言,请随意评论。Java Scanner可能很有用(因为它接受流),但功能没有那么强大。感谢您的长时间响应,但您可能错过了我想要的两个重要特性:1)我无法立即将整个字符串(您代码中pch指向的字符串)存储在内存中,而且我几乎找不到“边界”可以拆分字符串的位置。2)我不想一次匹配多个正则表达式,也不想一个接一个地查找它们。我的答案只是一个如何使用由提供的函数的示例,现在取决于您开始开发与您的需要相关的函数,如果您在函数中的某个位置被阻止,则再次返回我的问题(引用)“不提供公共API的正则表达式库”可以被认为是正则表达式(字符串、模式)的公共内容。感谢您的长时间响应,但您可能错过了我想要的两个重要特性:1)我不能拥有整个字符串(pch在您的代码中指出的字符串)在内存中,我几乎找不到可以拆分字符串的“边框”。2)我不想匹配多个正则表达式