正则表达式在 C 中不起作用
Regex is not working in C
当我在 shell 上使用它时,我正在使用正则表达式,它可以工作,但不能在 C 程序中使用。
有什么想法吗?
echo "abc:1234567890@werty.wer.sdfg.net" | grep -E "(\babc\b|\bdef\b):[0-9]{10}@([A-Za-z0-9].*)" //shell
reti = regcomp(®ex,"(\babc\b|\bdef\b):[0-9]{10}@([A-Za-z0-9].*)", 0); //c program
grep -E
使用一些增强的 ERE 语法,这意味着 {n,m}
量词大括号(以及 (
和 )
)不必转义(不是这种情况在 BRE 正则表达式中)。
您需要将 REG_EXTENDED
标志传递给 regcomp
,而且,由于您不能使用单词边界,请将第一个 \b
替换为 (^|[^[:alnum:]_])
"equivalent"。您不需要尾随 \b
,因为紧随其后的模式中有一个 :
:
const char *str_regex = "(^|[^[:alnum:]_])(abc|def):[0-9]{10}@([A-Za-z0-9].*)";
(^|[^[:alnum:]_])
部分匹配字符串的开头 (^
) 或 (|
) 除字母数字或下划线以外的字符。
完整 C demo:
#include <stdio.h>
#include <stdlib.h>
#include <regex.h>
int main (void)
{
int match;
int err;
regex_t preg;
regmatch_t pmatch[4];
size_t nmatch = 4;
const char *str_request = "abc:1234567890@werty.wer.sdfg.net";
const char *str_regex = "(^|[^[:alnum:]_])(abc|def):[0-9]{10}@([A-Za-z0-9].*)";
err = regcomp(&preg, str_regex, REG_EXTENDED);
if (err == 0)
{
match = regexec(&preg, str_request, nmatch, pmatch, 0);
nmatch = preg.re_nsub;
regfree(&preg);
if (match == 0)
{
printf("\"%.*s\"\n", pmatch[2].rm_eo - pmatch[2].rm_so, &str_request[pmatch[2].rm_so]);
printf("\"%.*s\"\n", pmatch[3].rm_eo - pmatch[3].rm_so, &str_request[pmatch[3].rm_so]);
}
else if (match == REG_NOMATCH)
{
printf("unmatch\n");
}
}
return 0;
}
字边界参考
从上面的链接看来 POSIX 支持它自己的词边界结构。
请注意,这些结构 [[:<:]]
、[[:>:]]
是 而不是 类。
鉴于此,并且使用 ERE 而不是 BRE,您应该能够做到这一点 -
reti = regcomp(®ex,"[[:<:]](abc|def)[[:>:]]:[0-9]{10}@([A-Za-z0-9].*)", REG_EXTENDED);
或者,由于[cf]
和:
之间是一个自然的词边界,所以可以简化为
reti = regcomp(®ex,"[[:<:]](abc|def):[0-9]{10}@([A-Za-z0-9].*)", REG_EXTENDED);
我还没有测试过,但它可能有效。
考虑到它实际上 不清楚 这在内部做了什么,
可能更好
坚持使用这种语法。
某些引擎,例如 Boost,具有 POSIX 选项,将语法自定义为 \<
和 \>
当我在 shell 上使用它时,我正在使用正则表达式,它可以工作,但不能在 C 程序中使用。
有什么想法吗?
echo "abc:1234567890@werty.wer.sdfg.net" | grep -E "(\babc\b|\bdef\b):[0-9]{10}@([A-Za-z0-9].*)" //shell
reti = regcomp(®ex,"(\babc\b|\bdef\b):[0-9]{10}@([A-Za-z0-9].*)", 0); //c program
grep -E
使用一些增强的 ERE 语法,这意味着 {n,m}
量词大括号(以及 (
和 )
)不必转义(不是这种情况在 BRE 正则表达式中)。
您需要将 REG_EXTENDED
标志传递给 regcomp
,而且,由于您不能使用单词边界,请将第一个 \b
替换为 (^|[^[:alnum:]_])
"equivalent"。您不需要尾随 \b
,因为紧随其后的模式中有一个 :
:
const char *str_regex = "(^|[^[:alnum:]_])(abc|def):[0-9]{10}@([A-Za-z0-9].*)";
(^|[^[:alnum:]_])
部分匹配字符串的开头 (^
) 或 (|
) 除字母数字或下划线以外的字符。
完整 C demo:
#include <stdio.h>
#include <stdlib.h>
#include <regex.h>
int main (void)
{
int match;
int err;
regex_t preg;
regmatch_t pmatch[4];
size_t nmatch = 4;
const char *str_request = "abc:1234567890@werty.wer.sdfg.net";
const char *str_regex = "(^|[^[:alnum:]_])(abc|def):[0-9]{10}@([A-Za-z0-9].*)";
err = regcomp(&preg, str_regex, REG_EXTENDED);
if (err == 0)
{
match = regexec(&preg, str_request, nmatch, pmatch, 0);
nmatch = preg.re_nsub;
regfree(&preg);
if (match == 0)
{
printf("\"%.*s\"\n", pmatch[2].rm_eo - pmatch[2].rm_so, &str_request[pmatch[2].rm_so]);
printf("\"%.*s\"\n", pmatch[3].rm_eo - pmatch[3].rm_so, &str_request[pmatch[3].rm_so]);
}
else if (match == REG_NOMATCH)
{
printf("unmatch\n");
}
}
return 0;
}
字边界参考
从上面的链接看来 POSIX 支持它自己的词边界结构。
请注意,这些结构 [[:<:]]
、[[:>:]]
是 而不是 类。
鉴于此,并且使用 ERE 而不是 BRE,您应该能够做到这一点 -
reti = regcomp(®ex,"[[:<:]](abc|def)[[:>:]]:[0-9]{10}@([A-Za-z0-9].*)", REG_EXTENDED);
或者,由于[cf]
和:
之间是一个自然的词边界,所以可以简化为
reti = regcomp(®ex,"[[:<:]](abc|def):[0-9]{10}@([A-Za-z0-9].*)", REG_EXTENDED);
我还没有测试过,但它可能有效。
考虑到它实际上 不清楚 这在内部做了什么,
可能更好
坚持使用这种语法。
某些引擎,例如 Boost,具有 POSIX 选项,将语法自定义为 \<
和 \>