[英]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>
提供的函数(如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
}
该函数将返回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.