正则表达式替换大量的搜索替换对

时间:2012-05-22 14:21:11

标签: python regex nlp text-processing

我希望能够进行大规模搜索并替换文档以进行文本规范化。

例如:

  1. 查找美国美国的所有用途,并替换为美国
  2. 查找所有&符号(&)并替换为
  3. 我还希望能够在不更改任何代码的情况下向系统添加新规则。因此,搜索替换对存储在数据存储中,这意味着任何人都可以添加,更新,删除规则。

    我一直在使用Python re模块,这是非常好的,理想情况下我想将一个元组列表传递给子命令,然后通过每个模块执行替换。除了迭代元组列表然后为每个元组创建一个正则表达式之外,有没有更好的方法来做到这一点 - 特别是对于大型文档而言,这是非常缓慢和低效的:

    replacements = [
      r('USA','United States Of America'),
      (r'U\.S\.A','United States Of America'),
      (r'US of A', 'United States of America')]
    
    for replacement in replacements:
      document = re.sub(replacement[0],replacement[1],document
    

3 个答案:

答案 0 :(得分:1)

您的所有示例都不需要正则表达式。为什么不尝试好的''字符串替换?

replacements = [
    ('USA','United States Of America'),
    ('U\.S\.A','United States Of America'),
    ('US of A', 'United States of America')]

for replacement in replacements:
    document = document.replace(replacement[0], replacement[1])

这看起来似乎很慢,但你应该在判断出来之前对它进行基准测试。 Python非常擅长这样的结果,结果可能让你感到惊讶。

如果你真的需要正则表达式,你可能会通过编译来获得巨大的提升:

replacements = [
    (re.compile('USA'),'United States Of America'),
    (re.compile('U\.S\.A'),'United States Of America'),
    (re.compile('US of A'), 'United States of America')]

for pattern, replacement in replacements:
    document = pattern.sub(replacement, document)

这为Python节省了每次使用它们时必须重新编译这些正则表达式的工作。

如果您在某些时候只需要regexp,请考虑在文档中进行两次传递:一次使用regexp,一次使用字符串替换。或者,如果您需要某些特定的替换顺序,您可以使用以下内容:

replacements = [
    (re.compile('USA'),'United States Of America'),
    ('foo', 'bar'),
    (re.compile('U\.S\.A'),'United States Of America'),
    ('spam', 'eggs'),
    (re.compile('US of A'), 'United States of America')]

for pattern, replacement in replacements:
    try:
        document = pattern.sub(replacement, document)
    except AttributeError:
        document = document.replace(pattern, replacement)

答案 1 :(得分:0)

查看Google Refine。

  

Google Refine,一种处理凌乱数据的强大工具

http://code.google.com/p/google-refine/

答案 2 :(得分:0)

我有一个Big Ass File,有6 MB的文字。它是几个Project Gutenberg文件的汇编。

试试这个:

reps = [
  (r'\bthousand\b','>>>>>1,000<<<<<'),
  (r'\bmillion\b',">>>>>1e6<<<<<"),
  (r'\b[Hh]undreds\b',">>>>>100's<<<<<"),
  (r'\bSherlock\b', ">>>> SHERLOCK <<<<")
  ]

t1=time.time()
out=[]  
rsMade=0
textLength=0
NewTextLen=0
with open('big.txt') as BigAssF:
    for line in BigAssF:
        textLength+=len(line)
        for pat, rep in reps:
            NewLine=re.subn(pat,rep,line)     

        out.append(NewLine[0])
        NewTextLen+=len(NewLine[0])
        rsMade+=NewLine[1]

print 'Text Length: {:,} characters'.format(textLength)
print 'New Text Length: {:,} characters'.format(NewTextLen)     
print 'Replacements Made: {}'.format(rsMade)     
print 'took {:.4} seconds'.format(time.time()-t1) 

打印:

Text Length: 6,488,666 characters
New Text Length: 6,489,626 characters
Replacements Made: 96
took 2.22 seconds

这似乎对我来说足够快。

您的代码行可能存在一些问题:

document = re.sub(replacement[0],replacement[1],document

如果那不是拼写错误。

您期望它有多快?