在参考资料的基础上,我修改了 ChunMinChang 收集的代码,并新增了 blankLineRemover 函数,用于将多个连续的空行合并成一个空行。这段 py 代码适合处理 Simulink Embedded Coder 生成的代码:生成的代码中可能包含一些在版本控制中令人头疼的注释,而为了可追溯性,我又不希望关闭代码注释。你也许在其他地方也能用上这段代码。

代码如有更新,请查看我的 github gist。

Python 代码

import re
import sys
import os.path

# Method 1: As described by saltycrane (https://www.saltycrane.com/blog/2007/11/remove-c-comments-python/):
#           This regular expression was created by Jeffrey Friedl and later modified by Fred Curtis.
#           Check the above link for details.
def removeComments(text):
    """ remove c-style comments.
        text: blob of text with comments (can include newlines)
        returns: text with comments removed
    """
    pattern = r"""
                            ##  --------- COMMENT ---------
           //.*?$           ##  Start of // .... comment
         |                  ##
           /\*              ##  Start of /* ... */ comment
           [^*]*\*+         ##  Non-* followed by 1-or-more *'s
           (                ##
             [^/*][^*]*\*+  ##
           )*               ##  0-or-more things which don't start with /
                            ##    but do end with '*'
           /                ##  End of /* ... */ comment
         |                  ##  -OR-  various things which aren't comments:
           (                ##
                            ##  ------ " ... " STRING ------
             "              ##  Start of " ... " string
             (              ##
               \\.          ##  Escaped char
             |              ##  -OR-
               [^"\\]       ##  Non "\ characters
             )*             ##
             "              ##  End of " ... " string
           |                ##  -OR-
                            ##
                            ##  ------ ' ... ' STRING ------
             '              ##  Start of ' ... ' string
             (              ##
               \\.          ##  Escaped char
             |              ##  -OR-
               [^'\\]       ##  Non '\ characters
             )*             ##
             '              ##  End of ' ... ' string
           |                ##  -OR-
                            ##
                            ##  ------ ANYTHING ELSE -------
             .              ##  Anything other char
             [^/"'\\]*      ##  Chars which doesn't start a comment, string
           )                ##    or escape
    """
    regex = re.compile(pattern, re.VERBOSE|re.MULTILINE|re.DOTALL)
    noncomments = [m.group(2) for m in regex.finditer(text) if m.group(2)]

    return "".join(noncomments)

# Method 2: Answered by Markus Jarderot on stackoverflow 
#           Link: https://stackoverflow.com/questions/241327/remove-c-and-c-comments-using-python
def commentRemover(text):
    def replacer(match):
        s = match.group(0)
        if s.startswith('/'):
            return " " # note: a space and not an empty string
        else:
            return s
    pattern = re.compile(
        r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
        re.DOTALL | re.MULTILINE
    )
    return re.sub(pattern, replacer, text)

# Combine multiple blank lines into one empty line
# Added by Technblogy.com
def blankLineRemover(text):
    def replacer(match):
        s = match.group(0)
        return ""
    pattern = re.compile(
        r'^\s*$',
        re.DOTALL | re.MULTILINE
    )
    return re.sub(pattern, replacer, text)

filenames = ['test.h']
for filename in filenames:
    with open(filename) as f:
        # use removeComments or commentRemover, two methods
        # uncmtFile = removeComments(f.read())
        uncmtFile = commentRemover(f.read())
        # blankLineRemover combines multiple blank lines into one empty line
        uncmtFile = blankLineRemover(uncmtFile)
        with open(os.path.splitext(filename)[0]+'.nocmt'+os.path.splitext(filename)[1], "w") as new_file:
            new_file.write(uncmtFile)

测试

输入文件:

/* This is a C-style comment. */
This is not a comment.
/* This is another
 * C-style comment.
 */
"This is /* also not a comment */"
// This is also a comment
This is still // a comment

     //blank lines

This is still /* a comment */
//blank comments
//blank comments
This is still /* a comment */ again
This is the final line

输出文件:


This is not a comment.

"This is /* also not a comment */"

This is still  

This is still  

This is still   again
This is the final line

References

Eliot:How to remove C style comments using Python

Markus Jarderot 的回答:Remove C and C++ comments using Python?

ChunMinChang:remove_c_style_comments.py

Technblogy.com 修改版:remove_c_style_comments.py


0 条评论

发表回复

Avatar placeholder

您的邮箱地址不会被公开。 必填项已用 * 标注