如何使用正则表达式在 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/,我尝试了以下正则表达式:(?&lt;![\/\*])\/(?![\/\*])。这至少涵盖了所有匹配项,但错误地匹配了包含行中的斜杠以及 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 代码中查找除法运算符?的主要内容,如果未能解决你的问题,请参考以下文章

C 语言高效编程与代码优化

C ++在字符串中查找特定数字

为啥除法被解析为正则表达式?

C语言如何定义一个算术表达式

正则表达式

VSCode 正则表达式查找和替换子匹配数学?