【问题标题】:Multiple string replacements on a 100mb file in python 2.6python 2.6中100mb文件的多个字符串替换
【发布时间】:2012-06-24 03:36:17
【问题描述】:

我有一个 100mb 的大文件,我想对其执行大约 5000 次字符串替换,实现此目的最有效的方法是什么?

没有比逐行读取文件并在每行执行 5000 次替换更好的方法吗?

在打开文件并对字符串执行 5000 次替换时,我还尝试使用 .read 方法将文件作为字符串读取,但这会更慢,因为它会复制整个文件的 5000 个副本。

此脚本必须在使用 python 2.6 的 Windows 上运行

提前致谢

【问题讨论】:

  • 您要替换的字符串是否有可能出现在多行中?即,多个带有空格的单词等。
  • 描述你正在做的替换
  • 要替换的字符串是 ids e.g. Abc-2454 将替换为 Gb-43。字符串永远不会分成多行。

标签: python windows string file replace


【解决方案1】:

按此顺序尝试以下操作,直到获得足够快的操作。

  1. 将文件读入一个大字符串并依次进行每次替换,覆盖相同的变量。

    with open(..., 'w') as f:
        s = f.read()
        for src, dest in replacements:
            s = s.replace(src, dest)
        f.seek(0)
        f.write(s)
    
  2. Memory map 文件,并编写一个自定义替换函数来执行替换。

【讨论】:

    【解决方案2】:

    我建议不要进行 5000 次搜索,而是一次搜索 5000 项:

    import re
    
    replacements = {
        "Abc-2454": "Gb-43",
        "This": "that",
        "you": "me"
    }
    
    pat = re.compile('(' + '|'.join(re.escape(key) for key in replacements.iterkeys()) + ')')
    repl = lambda match: replacements[match.group(0)]
    

    您现在可以将 re.sub 应用到整个文件,

    with open("input.txt") as inf:
        s = inf.read()
    
    s = pat.sub(repl, s)
    
    with open("result.txt") as outf:
        outf.write(s)
    

    或逐行,

    with open("input.txt") as inf, open("result.txt") as outf:
        outf.writelines(pat.sub(repl, line) for line in inf)
    

    【讨论】:

    • 适用于少量替换,但是当使用 5000 次替换时,我得到一个溢出错误正则表达式代码大小限制超出
    • @katrielalex:如果我们只“按预期”使用事物,那将是多么无聊的世界……
    【解决方案3】:

    您应该使用 open() 和 read() 读取文本,然后使用(编译的)正则表达式进行字符串替换。一个简短的例子:

    import re
    
    # read data
    f = open("file.txt", "r")
    txt = f.read()
    f.close()
    
    # list of patterns and what to replace them with
    xs = [("foo","bar"), ("baz","foo")]
    
    # do replacements
    for (x,y) in xs:
        regexp = re.compile(x)
        txt = regexp.sub(y, txt)
    
    # write back data
    f = open("file.txt", "w")
    f.write(txt)
    f.close()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-07
      • 1970-01-01
      • 2018-09-17
      • 1970-01-01
      • 2021-06-13
      • 2018-10-29
      相关资源
      最近更新 更多