2011-01-11 145 views
3

我对Python相当陌生,正在编写一系列脚本来在一些专有标记格式之间进行转换。我遍历逐行过的文件,然后基本上是做换人的大量(100-200),基本上可分为4类:在Python中进行大量搜索/替换的有效方法?

line = line.replace("-","<EMDASH>") # Replace single character with tag 
line = line.replace("<\\@>","@")  # tag with single character 
line = line.replace("<\\n>","")  # remove tag 
line = line.replace("\xe1","&bull;") # replace non-ascii character with entity 

的str.replace()函数似乎是相当有效的(当我检查分析输出时,数字相当低),但有没有更好的方法来做到这一点?我已经看到了一个函数作为参数的re.sub()方法,但我不确定这是否会更好?我想这取决于Python在内部做什么样的优化。以为我会在创建一个可能不太有用的大字典之前征求一些建议!

另外我做了一些标签解析(看起来有点像HTML,但不是HTML)。我识别标签是这样的:

m = re.findall('(<[^>]+>)',line) 

,然后做〜100搜索/替换匹配的标签内(主要是去除匹配),以及,例如:

m = re.findall('(<[^>]+>)',line) 
for tag in m: 
    tag_new = re.sub("\*t\([^\)]*\)","",tag) 
    tag_new = re.sub("\*p\([^\)]*\)","",tag_new) 

    # do many more searches... 

if tag != tag_new: 
    line = line.replace(tag,tag_new,1) # potentially problematic 

这里的任何效率的想法?

谢谢!

回答

3

str.replace()如果您打算进行基本搜索和替换,则效率更高,如果您需要复杂的模式匹配(因为否则您必须多次使用str.replace),re.sub显然会更有效。我建议你使用两者的组合。如果您有几种图案全部被一件东西取代,请使用re.sub。如果您只是在某些情况下需要将某个特定标签替换为另一个标签,请使用str.replace

您还可以通过使用较大的字符串(每行调用re.sub而不是一次)来提高效率。增加内存使用,但不应该是一个问题,除非该文件是巨大的,但也提高了执行时间。

0

如果你实际上并不需要正则表达式,只是在进行字面替换,string.replace()几乎肯定会更快。但即便如此,这里的瓶颈将是文件输入/输出,而不是字符串操作。

最好的解决方法,虽然很可能是使用cStringIO

0

根据您的操作文本的相关到不相关的部分的比率(不论是否在每个零件替换操作上重叠),尝试将输入分解为令牌并单独处理每个令牌可能会更有效。

由于您当前实现中的每个replace()都必须检查整个输入字符串,因此可能会很慢。如果你不是打破了该流成类似...

[<normal text>, <tag>, <tag>, <normal text>, <tag>, <normal text>] 
# from an original "<normal text><tag><tag><normal text><tag><normal text>" 

...那么你可以简单地看看,如果给定的令牌是一个标签,并在列表中替换它(然后''.join()结束)。

0

您可以通过一个函数对象re.sub而不是替换字符串,它需要的匹配对象,并返回替代,因此,例如

>>> r = re.compile(r'<(\w+)>|(-)') 
>>> r.sub(lambda m: '(%s)' % (m.group(1) if m.group(1) else 'emdash'), '<atag>-<anothertag>') 
'(atag)(emdash)(anothertag)' 

当然你也可以使用更复杂的函数对象,这拉姆达只是一个例子。

使用一个执行所有替换的正则表达式应该比迭代字符串多一些,但是如果执行了大量替换,调用计算替换的函数对象的开销可能会很大。

相关问题