使用Python删除C和C++注释?

c++ python c regex comments 匿名 | 2020-02-27 02:22:08

我正在寻找一个Python代码,它从字符串中删除C和C++注释。(假设字符串包含一个完整的C源文件。)
我意识到我可以将.match()子字符串与正则表达式进行匹配,但这并不能解决嵌套问题,也不能解决在

/* */

中包含
//
的问题。理想情况下,我更喜欢一个能够正确处理棘手情况的非纯实现。





12 答案



处理C++风格的注释、C风格的注释、字符串和简单嵌套。
< >代码> [代码] > /PRE> > BR>字符串,需要包括在内,因为注释标记不在里面开始注释。因为它们可以包含引号,否则会被识别为字符串分隔符。
Edit3:修复了这样的情况:通过将注释替换为空格而不是空字符串,合法表达式
int/**/x=5;
将变为无法编译的
intx=5;

2020-02-27 02:22:55
匿名


C(和C++)注释不能嵌套。正则表达式工作得很好:
//.*?\n|/\*.*?\*/

这需要“单行”标志(
Re.S
)因为一个C注释可以跨越多行。
def stripcomments(text):
return re.sub('//.*?\n|/\*.*?\*/', '', text, flags=re.S)

这段代码应该可以工作。
/EDIT:请注意,我上面的代码实际上是对行尾的假设!此代码在Mac文本文件上不起作用。但是,这可以相对容易地进行修改:
//.*?(\r\n?|\n)|/\*.*?\*/

此正则表达式应适用于所有文本文件,而不考虑其行尾(包括Windows、Unix和Mac行尾)。
/EDIT:MizardX和Brian(在注释中)对字符串的处理作出了有效的评论。我完全忘记了这一点,因为上面的正则表达式是从解析模块中提取的,该模块对字符串有额外的处理。MizardX的解决方案应该工作得很好,但它只处理双引号字符串。

2020-02-27 02:23:14
匿名


别忘了在C语言中,反斜杠换行在处理注释之前被删除,而三角图在处理注释之前被删除(因为??/是反斜杠的三角图)。我有一个C程序叫做SCC(条形码C/C++注释),这里是测试代码的一部分…
< PRE> >代码> [0 ] < /C> < /PRE> > BR>这并不能说明三叉树。请注意,一行的结尾可以有多个反斜杠,但是行拼接并不关心有多少反斜杠,但是后续的处理可能会。等。编写一个正则表达式来处理所有这些情况将是非常重要的(但这与不可能的不同)。

2020-02-27 02:23:28
匿名


这篇文章提供了对马库斯·贾德罗特代码改进的编码版本,这是阿蒂卡特在对马库斯·贾德罗特文章的评论中描述的。(感谢两者提供了原始代码,这节省了我很多工作。)
更全面地描述改进:改进保持了行编号的完整性。(这是通过保持C++中的C/C++注释替换字符串中的新行字符来完成的)。
当您希望生成包含行数的错误信息(例如,解析错误)时,C/C++注释删除函数的版本是适用的。文本)。
import re
def removeCCppComment( text ) :
def blotOutNonNewlines( strIn ) : # Return a string containing only the newline chars contained in strIn
return "" + ("\n" * strIn.count('\n'))
def replacer( match ) :
s = match.group(0)
if s.startswith('/'): # Matched string is //...EOL or /*...*/ ==> Blot out all non-newline chars
return blotOutNonNewlines(s)
else: # Matched string is '...' or "..." ==> Keep unchanged
return s
pattern = re.compile(
r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
re.DOTALL | re.MULTILINE
)
return re.sub(pattern, replacer, text)

2020-02-27 02:23:46
匿名

我不知道你是否熟悉代码> [0 ] < /Calp> ,UNIX BA[9 ](但Windows可用)文本解析程序,但我在这里找到了一个SED脚本,它将从文件中删除C/C++注释。它非常聪明;例如,如果在字符串声明中找到了“//'和‘/*’,则可以从以下代码中使用:”BR> < PRE> >代码> [代码] > /PRE> > BR>此程序中, >代码> [ 2 ] < /> > /Prime>是保存C/C++源代码的变量,最后 >代码> [3 ] < /Calp> < /Prime>将持有C/C++代码。删除评论。当然,如果文件在磁盘上,则可以将

input
output
变量作为指向这些文件的文件句柄(在读取模式下为
input
,在写入模式下为
output
)。
remccoms3.sed
是来自上述链接的文件,应该保存在磁盘上的可读位置。
sed
也可以在Windows上使用,默认情况下安装在大多数GNU/Linux发行版和Mac OS X上。
这可能比纯Python解决方案更好;无需重新设计轮子。

2020-02-27 02:22:27
匿名


在某些情况下,正则表达式的大小写会下降,例如字符串文本包含与注释语法匹配的子序列。你真的需要一个解析树来处理这个问题。

2020-02-27 02:23:57
匿名

你可以利用Py++来解析GCC的C++源。它使用GBCC C++编译器解析C++ +BR>源文件。更确切地说,
工具链看起来是这样的:
源代码被传递给GCC-XMLBR> GCC-XML,将其传递给GCC C++编译器BR> GCC-XML,生成GC++内部的
表示的C++程序的XML描述BR>。Py++使用Py GCC XML
包读取生成的GCC-XML
文件。底线——你可以肯定,你所有的声明都读对了。无论如何,这不是一个简单的解析。
@RE-based solutions-除非您限制输入(例如没有宏),否则您不可能找到一个正确处理所有可能的“尴尬”情况的RE。对于一个防弹的解决方案,你真的别无选择,只能利用真正的语法。

2020-02-27 02:24:10
匿名

对不起,这不是Python解决方案,但您也可以使用一个工具,它可以理解如何删除注释,比如C/C++预处理器。以下是GNU CPP的工作原理。

cpp -fpreprocessed foo.c

2020-02-27 02:24:17
匿名

也有一个非python的答案:使用程序StutCMT:
ToSCMT是一个简单的实用工具,在C中写的,BR>删除C、C++、BR>和java源文件的注释。在Unix文本处理程序的传统中,它既可以作为FIFO(先进先出)过滤器,也可以在命令行上接受参数

2020-02-27 02:24:25
匿名


以下操作对我有效:
from subprocess import check_output
class Util:
def strip_comments(self,source_code):
process = check_output(['cpp', '-fpreprocessed', source_code],shell=False)
return process
if __name__ == "__main__":
util = Util()
print util.strip_comments("somefile.ext")

这是子进程和cpp预处理器的组合。对于我的项目,我有一个名为“Util”的实用程序类,我保留了我使用/需要的各种工具。

2020-02-27 02:24:36
匿名


您并不需要一个解析树来完美地完成这项工作,但实际上您确实需要与编译器前端生成的内容等效的令牌流。这样的令牌流必须考虑所有的奇怪之处,如行连续的注释开始、字符串中的注释开始、trigraph规范化等。如果有令牌流,删除注释很容易。(我有一个工具可以生成这样的令牌流,比如,猜猜怎么着,生成真正解析树的真正解析器的前端:)。
这些标记由正则表达式单独识别的事实表明,原则上,您可以编写一个正则表达式来挑选注释词素。标记赋予器(至少是我们编写的)的集合正则表达式的真正复杂性表明,在实践中不能这样做;单独编写它们已经足够困难了。如果你不想做得很好,那么,上面的大多数重新解决方案都很好。
现在,你为什么想要删除注释超出了我的理解,除非你正在构建一个代码混淆器。在这种情况下,您必须完全正确地使用它。

2020-02-27 02:24:45
匿名


最近我在上一门课的时候遇到了这个问题,教授要求我们在提交javadoc进行代码评审之前,先从源代码中去掉javadoc。我们不得不多次这样做,但是我们不能永久地删除javadoc,因为我们还需要生成javadoc html文件。这是我做的一个小python脚本。由于javadoc以/**开头,以*/结尾,脚本会查找这些标记,但是可以修改脚本以满足您的需要。它还处理单行块注释和块注释结束但与块注释结束在同一行上仍有未注释代码的情况。我希望这有帮助!
警告:此脚本修改传入文件的内容并将其保存到原始文件。最好在其他地方有备份
#!/usr/bin/python
"""
A simple script to remove block comments of the form /** */ from files
Use example: ./strip_comments.py *.java
Author: holdtotherod
Created: 3/6/11
"""
import sys
import fileinput
for file in sys.argv[1:]:
inBlockComment = False
for line in fileinput.input(file, inplace = 1):
if "/**" in line:
inBlockComment = True
if inBlockComment and "*/" in line:
inBlockComment = False
# If the */ isn't last, remove through the */
if line.find("*/") != len(line) - 3:
line = line[line.find("*/")+2:]
else:
continue
if inBlockComment:
continue
sys.stdout.write(line)

2020-02-27 02:24:58
匿名


World is powered by solitude
备案号:湘ICP备19012068号