【问题标题】:Trying to skip lines that match regex when writing to file, but new file has extra new lines写入文件时尝试跳过与正则表达式匹配的行,但新文件有额外的新行
【发布时间】:2020-07-19 03:52:41
【问题描述】:

这是我在here 提出的一个问题的衍生。

我正在尝试根据输入字典设置一种可以编辑文本文件的方法。这是我目前所拥有的:

info = {'#check here 1':{'action':'read'}, '#check here 2':{'action':'delete'}}

search_pattern = re.compile(r'.*(#.+)')        

    with open(input_file_name, "r") as old_file, open(output_file_name, "w+") as new_file:
        lines = old_file.readlines()

        for line in lines:
            edit_point = search_pattern.search(line)
            if edit_point:
                result = edit_point.group(1)
                if result in info and info[result]["action"] == "insert":#insert new lines to file
                    print("insert information to file")
                    new_file.write("\n".join([str(n) for n in info[result]["new_lines"]]))
                    new_file.write(result)
                elif result in info and info[result]["action"] == "delete":#skip lines with delete action
                    print("found deletion point. skipping line")
                else:#write to file any line with a comment that is not in info
                    new_file.write(line)
            else:#write lines that do not match regex for (#.*)
                new_file.write(line)

基本上,当您提交字典时,程序会遍历文件,搜索 cmets。如果评论在字典中,它将检查相应的操作。如果操作是插入,它会将行写入文件。如果它被删除,它将跳过该行。任何没有注释的行都应该写入新文件。

我的问题是,当我从文件中删除一行时,它们以前所在的位置似乎有额外的新行。例如,如果我有一个列表:

hello world

how are you #keep this
I'm fine #check here 2
whats up

我希望输出是:

hello world

how are you #keep this
whats up

但我有一个空行:

hello world

how are you #check here 2

whats up

我怀疑这是我最后的 else 语句,它将任何与 edit_point 不匹配的行写入文件,在本例中为新行。但是,我的理解是 for 循环应该逐行执行,并且只需执行该行。谁能告诉我我在这里缺少什么?

【问题讨论】:

  • 您的代码、输入文本和输出文本不匹配。您的 info 字典没有 '#keep this''#delete this' 的键,因此它始终为 False 并分支到 else 语句,在这种情况下它应该只打印整个文件。
  • 我尝试了您的代码,但文件未修改。您确定您发布的代码正是您拥有的代码吗?
  • 代码正是我所拥有的。该文件的唯一区别是我在这里放置了#delete,而不是#check here 2,以描述预期的行为。我已更新文件以反映这一点。

标签: python regex file writetofile


【解决方案1】:

这看起来有点复杂,您将读取和写入逻辑与处理逻辑混合在一起,这使得很难跟踪正在发生的事情。试试这种方法:

from enum import Enum
from typing import Dict, List


class Action(Enum):
    KEEP = "keep"
    REMOVE = "remove"


definition = {
    "#KEEP": {"action": Action.KEEP},
    "#REMOVE": {"action": Action.REMOVE},
}


def clean_comments(
    lines: List[str], definition: Dict[str, Dict[str, str]]
) -> List[str]:

    # Keep a list of the lines that should be in the output
    output: List[str] = []

    # Loop the lines
    for line in lines:

        # If any of the comments in the definition is found, process further
        if any([comment in line for comment in definition.keys()]):

            # Figure out what to do
            for comment, details in definition.items():
                if comment in line:

                    if details["action"] == Action.KEEP:
                        output.append(line)
                        break

                    elif details["action"] == Action.REMOVE:
                        break

        # Keep all other lines
        else:
            output.append(line)

    return output


# Your data here...
with open("test_input.txt", "r") as f:
    lines = f.readlines()

# Use the function to clean the text
clean_text = "".join(clean_comments(lines, definition))

# Show the output
print(clean_text)

# Write to file
with open("test.txt", "w") as f:
    f.write(clean_text)

输出:

hello world

how are you #KEEP: This line will be kept in the output file
whats up

【讨论】:

    猜你喜欢
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    相关资源
    最近更新 更多