【问题标题】:Replacing words in text file using a dictionary使用字典替换文本文件中的单词
【发布时间】:2017-08-25 15:16:35
【问题描述】:

我正在尝试打开一个文本文件,然后通读它,用存储在字典中的字符串替换某些字符串。

根据对How do I edit a text file in Python? 的回答,我可以在替换之前提取字典值,但循环遍历字典似乎更有效。

代码不会产生任何错误,也不会做任何替换。

import fileinput

text = "sample file.txt"
fields = {"pattern 1": "replacement text 1", "pattern 2": "replacement text 2"}

for line in fileinput.input(text, inplace=True):
    line = line.rstrip()
    for i in fields:
         for field in fields:
             field_value = fields[field]

             if field in line:
                  line = line.replace(field, field_value)


             print line

【问题讨论】:

  • 到底发生了什么?你能举一个输入和预期输出的例子吗?
  • 当你说“不做任何替换”时,你的意思是在打印行吗?
  • 您的模式看起来如何?是那些词吗?

标签: python python-2.7 dictionary in-place


【解决方案1】:

我使用items() 来迭代您的fields 字典中的keyvalues

我用continue 跳过空白行,用rstrip() 清理其他空白行

我将line 中的每个keys 替换为fields 字典中的values,并用print 编写每一行。

import fileinput

text = "sample file.txt"
fields = {"pattern 1": "replacement text 1", "pattern 2": "replacement text 2"}


for line in fileinput.input(text, inplace=True):
    line = line.rstrip()
    if not line:
        continue
    for f_key, f_value in fields.items():
        if f_key in line:
            line = line.replace(f_key, f_value)
    print line

【讨论】:

  • 谢谢,这行得通。我使用了一个变体:code for line in fileinput.input(text, inplace=False): line = line.rstrip() if not line: continue for f_key, f_value in field_value_dict.items(): if f_key in line: line = line.replace(f_key, f_value) file.write(line + '\n') file.close() code
【解决方案2】:

如果您可以找到覆盖所有键的正则表达式模式,则可以使用re.sub 来获得非常有效的解决方案:您只需要一次通过,而不是为每个搜索词解析整个文本。

在您的标题中,您提到了“替换单词”。在这种情况下,'\w+' 可以正常工作。

import re

fields = {"pattern 1": "replacement text 1", "pattern 2": "replacement text 2"}

words_to_replace = r'\bpattern \d+\b'

text = """Based on answers to How do I edit a text file in Python? pattern 1 I could pull out
the dictionary values before doing the replacing, but looping through the dictionary seems more efficient.
Test pattern 2
The code doesn't produce any errors, but also doesn't do any replacing. pattern 3"""

def replace_words_using_dict(matchobj):
    key = matchobj.group(0)
    return fields.get(key, key)

print(re.sub(words_to_replace, replace_words_using_dict, text))

它输出:

Based on answers to How do I edit a text file in Python? replacement text 1 I could pull out
the dictionary values before doing the replacing, but looping through the dictionary seems more efficient.
Test replacement text 2
The code doesn't produce any errors, but also doesn't do any replacing. pattern 3

另外,在原地修改文件时要非常小心。我建议你用替换写第二个文件。一旦您 100% 确定它可以完美运行,您就可以切换到 inplace=True

【讨论】:

  • 您可以使用字典的键来获取匹配正则表达式,例如words_to_replace = "|".join(fields.keys()) 替换所有出现,或 words_to_replace = r"\b({})\b".format("|".join(fields.keys())) 到要求出现是孤立的词
  • 是的,这也可以。如果 regex union 太慢,可以创建一个 Regex trie:stackoverflow.com/a/42789508/6419007
【解决方案3】:

刚刚弄清楚如何通过遍历字典(仅匹配整个单词)一次性替换 txt 文件中的许多不同单词。 如果我想用“John”替换“1”,但最终将“12”变成“John2”,那会很烦人。以下代码对我有用。

import re

match = {}  # create a dictionary of words-to-replace and words-to-replace-with

f = open("filename","r")
data = f.read() # string of all file content

def replace_all(text, dic):
    for i, j in dic.items():
        text = re.sub(r"\b%s\b"%i, j, text) 
        # r"\b%s\b"% enables replacing by whole word matches only
    return text

data = replace_all(data,match)
print(data) # you can copy and paste the result to whatever file you like

【讨论】:

    【解决方案4】:

    如果你对 Python 比较熟悉,可以参考官方文档中的提示:

    7.1. string — Common string operations

    还有 subclass,即 Template 类,您可以在其中以某种方式定义每个单独的世界都将是一个新的 placeholder,然后使用 @ 987654322@您可以获得一个不错且可靠的解决方案。

    【讨论】:

      【解决方案5】:
      import fileinput
      
      text = "sample file.txt"
      fields = {"pattern 1": "replacement text 1", "pattern 2": "replacement text 2"}
      
      for line in fileinput.input(text, inplace=True):
          line = line.rstrip()
          for field in fields:
              if field in line:
                  line = line.replace(field, fields[field])
      
          print line
      

      【讨论】:

        【解决方案6】:

        我会这样做:

        fields = {"pattern 1": "replacement text 1", "pattern 2": "replacement text 2"}
        
        with open('yourfile.txt', 'w+') as f:
            s = f.read()
            for key in fields:
                s = s.replace(key, fields[key])
            f.write(s)
        

        【讨论】:

        • 这就是为什么就地修改文件是一个非常糟糕的主意的原因。您的代码会擦除 'yourfile.txt'
        • 抱歉,我打字太匆忙了,s.replace() 需要分配给s,我修正了错字。此外,代码确实会擦除文件,但会将其替换为“更新”字符串,显然如果文件包含关键信息,请在替换内容之前对副本进行操作。
        • 您的代码仍然会擦除文件,然后读取它,然后用任何内容替换它,然后什么都不保存到文件中。您能否在发布之前测试您的潜在危险代码?
        猜你喜欢
        • 2015-07-12
        • 2021-12-10
        • 2022-09-23
        • 2020-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多