0

可能重复:
Python 3 正则表达式查找多行注释

我需要一些关于如何做到这一点的意见,非常感谢您的意见,我查看了其他帖子,但没有一个符合我的要求。

如何从python中的文件中 删除行使用python从文本文件中删除行

我需要根据提供的输入字符串匹配文件中的多行注释。

例子:-

假设文件“test.txt”有以下注释,如果 inputstring="This is a test, scriptwritten" 这个注释需要从文件中删除

import os
import sys

import re
import fnmatch

def find_and_remove(haystack, needle):
    pattern = re.compile(r'/\*.*?'+ needle + '.*?\*/', re.DOTALL)
    return re.sub(pattern, "", haystack)

for path,dirs,files in os.walk(sys.argv[1]):
    for fname in files:
        for pat in ['*.cpp','*.c','*.h','*.txt']:
            if fnmatch.fnmatch(fname,pat):
                fullname = os.path.join(path,fname)
                with open(fullname, "r") as f:
                    find_and_remove(f, r"This is a test, script written")

错误:-

Traceback (most recent call last):
  File "comment.py", line 16, in <module>
    find_and_remove(f, r"This is a test, script written")
  File "comment.py", line 8, in find_and_remove
    return re.sub(pattern, "", haystack)
  File "/usr/lib/python2.6/re.py", line 151, in sub
    return _compile(pattern, 0).sub(repl, string, count)
TypeError: expected string or buffer
4

3 回答 3

3

当我看到这个问题时首先想到的是“状态机”,而每当我想到 python 中的“状态机”时,首先想到的是“生成器”,也就是产量:

def skip_comments(f):
    """
    Emit all the lines that are not part of a multi-line comment.
    """
    is_comment = False

    for line in f:
        if line.strip().startswith('/*'):
            is_comment = True

        if line.strip().endswith('*/'): 
            is_comment = False
        elif is_comment:
            pass
        else:
            yield line


def print_file(file_name):
    with file(file_name, 'r') as f:
        skipper = skip_comments(f)

        for line in skipper:
            print line,

编辑:user1927396 通过指定它只是一个要排除的特定块来提高赌注,其中包含特定的文本。由于它在注释块内,我们不会预先知道是否需要拒绝该块。

我的第一个想法是缓冲区。确认。便便。我的第二个想法是 15 年来一直萦绕在我脑海中但直到现在从未使用过的令人难以忘怀的副歌:“状态机堆栈”......

def squelch_comment(f, first_line, exclude_if):
    """
    Comment is a multi-line comment that we may want to suppress
    """
    comment = [first_line]

    if not first_line.strip().endswith('*/'):
        for line in f:

            if exclude_if in line:
                comment = None

            if comment and len(comment):
                comment.append(line)

            if line.strip().endswith('*/'):
                break

    if comment:
        for comment_line in comment:
            yield '...' + comment_line


def skip_comments(f):
    """
    Emit all the lines that are not part of a multi-line comment.
    """
    for line in f:
        if line.strip().startswith('/*'):
            # hand off to the nested, comment-handling, state machine
            for comment_line in squelch_comment(f, line, 'This is a test'):
                yield comment_line
        else:
            yield line


def print_file(file_name):
    with file(file_name, 'r') as f:
        for line in skip_comments(f):
            print line,
于 2013-01-09T06:59:42.383 回答
1

这应该在原则上有效

def skip(file, lines):
 cline = 0
 result = ""
 for fileLine in file.read():
  if cline not in lines:
   result += fileLine
  cline += 1
 return result

行必须是数字列表,文件必须是打开的文件

于 2013-01-09T07:42:02.427 回答
1

这一个在请求中执行它:删除所有包含所需字符串的多行注释:

把它放在一个名为program.txt

/*
 * This is a test, script written
 * This is a comment line
 * Multi-line comment
 * Last comment
 *
 */

some code

/*
 * This is a comment line
 * And should 
 *     not be removed
 *
 */

more code

然后搜索和替换。只要确保needle不引入一些正则表达式特殊字符。

import re

def find_and_remove(haystack, needle):
    pattern = re.compile(r'/\*.*?'+ needle + '.*?\*/', re.DOTALL)
    return re.sub(pattern, "", haystack)

# assuming your program is in a file called program.txt
program = open("program.txt", "r").read()

print find_and_remove(program, r"This is a test, script written")

结果:

some code

/*
 * This is a comment line
 * And should 
 * not be removed
 *
 */

more code

它调整了相关问题中的正则表达式

编辑代码中的最后一部分:

for path,dirs,files in os.walk(sys.argv[1]):
    for fname in files:
        for pat in ['*.cpp','*.c','*.h','*.txt']:
            if fnmatch.fnmatch(fname,pat):
                fullname = os.path.join(path,fname)
                # put all the text into f and read and replace...
                f = open(fullname).read()
                result = find_and_remove(f, r"This is a test, script written")

                new_name = fullname + ".new"
                # After testing, then replace newname with fullname in the 
                # next line in order to replace the original file.
                handle = open(new_name, 'w')
                handle.write(result)
                handle.close()

确保在needle您转义所有正则表达式特殊字符,例如().,如果您的文本包含括号,例如,(any text)它们应该出现在needleas\(any text\)

于 2013-01-09T07:51:44.297 回答