正则表达式,用于识别C中的变量声明

dav*_*ler 2 c regex lex

我正在使用正则表达式来识别C中的变量声明,我已经得到了这个.

[a-zA-Z_][a-zA-Z0-9]*
Run Code Online (Sandbox Code Playgroud)

有没有更好的解决方案?

yey*_*eyo 6

用于识别C中的变量声明的模式.查看传统声明,我们看到:

int variable;
Run Code Online (Sandbox Code Playgroud)

如果是这种情况,则应该先测试type关键字,以避免匹配其他内容,如字符串或使用预处理器定义的常量

(?:\w+\s+)([a-zA-Z_][a-zA-Z0-9]+)
Run Code Online (Sandbox Code Playgroud)

变量名位于\ 1中.

您需要的功能是后视/前瞻.

2015年7月11日更新

以前的正则表达式无法将某些变量与_中间的任何位置匹配 .要解决这个问题,只需要添加_到第一个捕获组的第二部分,它还会假设两个或更多字符的变量名称,这就是它在修复后的样子:

(?:\w+\s+)([a-zA-Z_][a-zA-Z0-9_]*)
Run Code Online (Sandbox Code Playgroud)

然而,这个正则表达式有许多误报,goto jump;其中之一,坦率地说它不适合这项工作,因此,我决定创建另一个正则表达式以涵盖更广泛的案例,虽然它远非完美,这里是:

\b(?:(?:auto\s*|const\s*|unsigned\s*|signed\s*|register\s*|volatile\s*|static\s*|void\s*|short\s*|long\s*|char\s*|int\s*|float\s*|double\s*|_Bool\s*|complex\s*)+)(?:\s+\*?\*?\s*)([a-zA-Z_][a-zA-Z0-9_]*)\s*[\[;,=)]
Run Code Online (Sandbox Code Playgroud)

我已经使用Ruby,Python和JavaScript测试了这个正则表达式,它适用于常见情况,但在某些情况下它失败了.此外,正则表达式可能需要一些优化,但在保持几个正则表达式引擎的可移植性的同时很难进行优化.

测试恢复

unsignedchar *var;                   /* OK, doesn't match */
goto **label;                        /* OK, doesn't match */
int function();                      /* OK, doesn't match */
char **a_pointer_to_a_pointer;       /* OK, matches +a_pointer_to_a_pointer+ */
register unsigned char *variable;    /* OK, matches +variable+ */
long long factorial(int n)           /* OK, matches +n+ */
int main(int argc, int *argv[])      /* OK, matches +argc+ and +argv+ (needs two passes) */
const * char var;                    /* OK, matches +var+, however, it doesn't consider +const *+ as part of the declaration */
int i=0, j=0;                        /* 50%, matches +i+ but it will not match j after the first pass */
int (*functionPtr)(int,int);         /* FAIL, doesn't match (too complex) */
Run Code Online (Sandbox Code Playgroud)

误报

以下情况很难用可移植的正则表达式覆盖,文本编辑器使用上下文来避免突出显示引号内的文本.

printf("int i=%d", i);               /* FAIL, match i inside quotes */
Run Code Online (Sandbox Code Playgroud)

误报(语法错误)

如果在应用正则表达式之前测试源文件的语法,则可以修复此问题.使用GCC和Clang,只需传递-fsyntax-only标志来测试源文件的语法,而无需编译它

int char variable;                  /* matches +variable+ */
Run Code Online (Sandbox Code Playgroud)