用re替换文件中的单词

Posted

技术标签:

【中文标题】用re替换文件中的单词【英文标题】:Replacing words in a file with re 【发布时间】:2019-04-10 07:45:47 【问题描述】:

我有一个函数可以遍历文本文件,将单词与字典中的键匹配,并将这些单词更改为键值:

def replace_operators(text):
    operators = 'order': '"order"'
    f = open(text, 'r').read()

    for k, v in operators.items():
        cleaned = re.sub(r"\b%s\b" % k, v, f)
        f = open(text, 'w')
        f.truncate(0)
        f.close()
        text_file = open(text, 'w')
        text_file.write(cleaned)
        text_file.close()

这很好,但是当我向字典中添加另一个键时,我收到:

TypeError:预期的字符串或类似字节的对象

我尝试了在清理后的行中用 str(f) 替换 f 的解决方案(由 this 回答建议),但是这只会将以下行写入我的输出文件:

<_io.textiowrapper mode="w" encoding="cp1252">

有谁知道我如何添加更多键而不会出现这种错误?

【问题讨论】:

在您第一次通过for k, v in ... 循环后,f 是关闭的文件对象,而不是初始读取的结果。 另外,如果你连续以写模式打开文件,每次迭代都会清除所有之前存储的文件内容 您的两点都很有道理,谢谢。您有什么建议的解决方案吗? 一个开始的地方是将'w' 更改为'a',这意味着追加,然后将 f.close() 和 text_file.close() 移到 for 循环之外。 【参考方案1】:

您不需要循环,也不需要多次替换和写入文件。一个非常有效的方法是:

打开并读取文件 使用正则表达式替换函数与 lambda,尝试将文本中的单词与字典匹配,如果找不到则返回相同的单词 打开并写入文件(或新文件)

像这样:

import re

text = "input.txt"

operators = 'order': '"order"', 'matter':'"matter"'
with open(text, 'r') as f:
    contents = f.read()

cleaned = re.sub(r"\b(\w+)\b",lambda m : operators.get(m.group(1),m.group(1)),contents)

with open("new_"+text, 'w') as f:
    f.write(cleaned)

这个鲜为人知的功能非常强大。它允许传递一个 function 作为替换(不是字符串)。此函数将匹配作为输入,并返回必须替换匹配的字符串作为输出。我的函数是匿名函数(lambda):

lambda m : operators.get(m.group(1),m.group(1))

所以如果匹配的单词在字典中,则返回 & 替换为值,否则返回原始单词。

所有这些都没有循环和O(1) 单词查找,即使您的字典中有 很多 项也非常快(与线性第 n 次替换方法或构建关键字列表相反使用"|".join(),当您有 1000 多个要搜索/替换的项目时开始抓取)

【讨论】:

非常好,运行良好,运行速度非常快,谢谢。

以上是关于用re替换文件中的单词的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式仅用替换文件中的单词替换单词

用文件中的另一个词替换特定词[关闭]

从.txt文件中替换一行中的多个单词[重复]

查找和替换文件中的单词/行

sed 用多次出现的单词替换单词分隔符

如何在bash中替换文件中的单词