如何使用正则表达式在 C 代码中查找除法运算符?
Posted
技术标签:
【中文标题】如何使用正则表达式在 C 代码中查找除法运算符?【英文标题】:How can I grep for division operator in C code with regex? 【发布时间】:2022-01-22 21:52:40 【问题描述】:在一堆 C 代码中,我想找到所有出现的除法(如果它们检查除以零,则检查它们)。因此,我正在尝试构建一个正则表达式,可用于 grep 以查找所有 /
。
我构建了一些案例,什么应该匹配,什么不应该,因为它是例如包含、评论等:
应该匹配的行:
int i = 5/0; //and a comment in line
double d = 58 * 17 / 16 / (3 + 5)
不应该匹配的行:
#include <include/pathes.h> (might have whitespaces in front)
bla // double slash for comments
/* single slash with * in block comments*/
// slashes inside comments / should be ignored
// slashes inside comments / should be ignored (with whitespaces in front)
感谢https://regex101.com/,我尝试了以下正则表达式:(?<![\/\*])\/(?![\/\*])
。这至少涵盖了所有匹配项,但错误地匹配了包含行中的斜杠以及 cmets 中的斜杠。
如何以某种方式改进正则表达式,使 include 中的斜线和 cmets 中的斜线被忽略? (我知道,多行 cmets 中也可能有斜线,这不是那么容易 grep,但我必须从某个地方开始。)
有没有比 grepping 寻找/
找出源代码中的部门更好的解决方案?
【问题讨论】:
您的编译器可以为您执行此操作。 我没有看到排除#include
行中匹配项的好方法,但您可以考虑扫描预处理的源代码,其中不包含任何内容。这也将帮助您找到由宏产生的除法运算。另一方面,它也会对包含的内容产生匹配。
您可以使用| grep -v '#include'
删除包含行。
@dbush 这听起来很有趣。如果您能更详细地解释这一点,我将不胜感激。提前致谢。
@meddle0106 在这种情况下 grep 肯定找不到。您最好购买静态分析工具。
【参考方案1】:
你最好的选择是你的编译器。
您的下一个最佳选择是使用 perl 过滤源并删除 cmets 和包含。
给定:
$ cat file
int i = 5/0; //and a comment in line
double d = 58 * 17 / 16 / (3 + 5) /* old single line comment */
double f=3/0; /* multiline comment
with / in it
end */
#include <include/pathes.h> (might have whitespaces in front)
bla // double slash for comments
/* single slash with /* in block comments*/
// slashes inside comments / should be ignored
// slashes inside comments / should be ignored (with whitespaces in front)
您可以像这样删除所有 cmets 和包含:
perl -0777 -pE 's/\/\*(\*(?!\/)|[^*])*\*\///g;
s/^\s*#.*//mg; s/[\/]2.*//g;' file
打印:
int i = 5/0;
double d = 58 * 17 / 16 / (3 + 5)
double f=3/0;
bla
然后在上面做一个简单的grep
:
perl -0777 -pE 's/\/\*(\*(?!\/)|[^*])*\*\///g;
s/^\s*#.*//mg; s/[\/]2.*//g;' file | grep '/'
打印:
int i = 5/0;
double d = 58 * 17 / 16 / (3 + 5)
double f=3/0;
或者,如果您想在perl
中完成所有操作并保留
/* single line comments */
和 // comments
代码后:
perl -0777 -nE 's/(\/\*(?:\*(?!\/)|[^*])*\*\/)/($1=~qr"\R") ? "" : $1/eg;
s/^\s*#.*//mg;
for $l (split /\R+/, $_)
@parts=split /(?:\/\/)|(?:\/\*)/, $l;
say $l if $parts[0]=~/\//;
' file
打印:
int i = 5/0; //and a comment in line
double d = 58 * 17 / 16 / (3 + 5) /* old single line comment */
double f=3/0;
限制
这是严格面向行的(除了删除多行注释)。有合法的 C 语句跨越多行。这只会找到注释中没有/
的单行。要使用 C 语句与可能不完整的 C 行,您需要一个 C 代码解析器(例如您的编译器)。
【讨论】:
以上是关于如何使用正则表达式在 C 代码中查找除法运算符?的主要内容,如果未能解决你的问题,请参考以下文章