我试图使用正则表达式来解析源文件并在C程序中搜索以" LOG"开头的函数。并且可能会或可能不会跟随类[1248AFM]中的第二个字符,然后是一个左括号。这是在Windows下使用mingw开发的,但最终将使用gcc在Linux下编译和运行。我使用Jan Goyvaerts正则表达式教程作为指导,看起来我之后的是上面显示的括号表达式表达式的零或一个匹配。零或一个听起来很像问号元字符,但在我的实验中,我还没有能够按照括号表达式来工作。为了说明我想要做的事情,我有如下所示的短程序。理想情况下,我想只在str1和str2上匹配。如果我如图所示编译并运行它,我就无法获得任何匹配。如果我在括号表达式后面留下问号,我只在str2上得到一个匹配,这就是我所期望的。除了问号之外,我还尝试了{0,1}形式的区间量词,但也没有成功。我应该使用除括号表达式以外的其他东西吗?
戴夫
#include <stdio.h>
#include <regex.h>
int main(int argc, char **argv) {
regex_t regex;
int rtn = regcomp(®ex, "LOG[1248AFM]?(", 0);
if (rtn) {
printf("compile failed\n");
return(1);
}
char *str1 = " LOG(";
char *str2 = " LOGM(";
char *str3 = " LOG";
char *str4 = " LOGJ(";
int rtn1 = regexec(®ex, str1, 0, NULL, 0);
int rtn2 = regexec(®ex, str2, 0, NULL, 0);
int rtn3 = regexec(®ex, str3, 0, NULL, 0);
int rtn4 = regexec(®ex, str4, 0, NULL, 0);
printf("str1: %d\nstr2: %d\nstr3: %d\nstr4: %d\n",
rtn1, rtn2, rtn3, rtn4);
return(0);
}
答案 0 :(得分:2)
像Casimir et Hippolyte所说的那样:当我做评论时,你需要逃脱逃过我的?
。问题是你使用字符串文字,这意味着你必须逃避转义。
编辑:?
是基本正则表达式的Gnu扩展名。但问题仍然存在:需要逃避C语言中的转义。
#include <stdio.h>
#include <regex.h>
int main(int argc, char **argv) {
regex_t regex;
// Gnu extension
// int rtn = regcomp(®ex, "LOG[1248AFM]\\?(",0);
// Basic regular expression
int rtn = regcomp(®ex, "LOG[1248AFM]\\{0,1\\}(",0);
if (rtn) {
printf("compile failed\n");
return(1);
}
char *str1 = " LOG(";
char *str2 = " LOGM(";
char *str3 = " LOG";
char *str4 = " LOGJ(";
int rtn1 = regexec(®ex, str1, 0, NULL, 0);
int rtn2 = regexec(®ex, str2, 0, NULL, 0);
int rtn3 = regexec(®ex, str3, 0, NULL, 0);
int rtn4 = regexec(®ex, str4, 0, NULL, 0);
printf("str1: %d\nstr2: %d\nstr3: %d\nstr4: %d\n",
rtn1, rtn2, rtn3, rtn4);
return(0);
}
给出
str1: 0
str2: 0
str3: 1
str4: 1
答案 1 :(得分:2)
这里的部分问题源于不同正则表达方言的特征集之间的不幸混淆。
长话短说,使用REG_EXTENDED
,您可以获得某些正则表达式构造的grep -E
(又名egrep
)含义。
"e?(grep){3,7}"
不需要反斜杠 - 问号?
使前一个表达式可选,括号进行分组,花括号表示广义重复(在这种情况下,重复三到七次)。
如果没有REG_EXTENDED
,您将获得BRE语义,这需要在每个语句之前使用反斜杠。当然,在C字符串中,为了产生一个文字反斜杠,你需要两个反斜杠,因为反斜杠是一个通用的C字符串转义字符。
"e\\?\\(grep\\)\\{3,7\\}"
接下来是对历史的简要解释,但你可以在这里停止阅读并完成。
基本正则表达式(BRE)基于Ken Thompson的原始grep
的功能集。原始grep
没有分组括号,带有大括号的广义量化,甚至没有表达可选性的问号。然而,POSIX标准编码了一种表达这些结构的方法,即使在BRE中也是如此。坚持下去。
扩展正则表达式(ERE)基于egrep
的特征集,其主要是Al Aho的grep
的扩展。它引入了许多新功能,以及不同的内部架构,基于当时对自动机理论应用于字符串匹配的持续研究(我们在这里谈论早期到中期)。
当这些由POSIX标准化时,标准引入了特征奇偶校验,但这些方言的表面语法不同。在BRE方言中引入了grep
语法的某种古怪扩展,其中反斜杠启用,而不是转义,某些字符的特殊含义。这使得BRE向后兼容原始grep
(只要您不必在正则表达式中使用反斜杠,之前它们没有特殊含义),这是一个重要的考虑因素,但无可否认是设计疣。 / p>