我正在尝试更正一些包含一些非常典型的扫描错误(我误认为是I,反之亦然)的文本。基本上我想有re.sub
替换字符串依靠的次数“我”被检测到,这样的事情:Python:使用re.sub多次替换多个子字符串
re.sub("(\w+)(I+)(\w*)", "\g<1>l+\g<3>", "I am stiII here.")
什么是实现这一目标的最佳方式是什么?
我正在尝试更正一些包含一些非常典型的扫描错误(我误认为是I,反之亦然)的文本。基本上我想有re.sub
替换字符串依靠的次数“我”被检测到,这样的事情:Python:使用re.sub多次替换多个子字符串
re.sub("(\w+)(I+)(\w*)", "\g<1>l+\g<3>", "I am stiII here.")
什么是实现这一目标的最佳方式是什么?
传递函数作为替换字符串,如the docs中所述。你的功能可以识别这个错误,并基于此创建最佳替代。
def replacement(match):
if "I" in match.group(2):
return match.group(1) + "l" * len(match.group(2)) + match.group(3)
# Add additional cases here and as ORs in your regex
re.sub(r"(\w+)(II+)(\w*)", replacement, "I am stiII here.")
>>> I am still here.
(请注意,我修改你的正则表达式,从而重复是会出现在一个组。)
在我看来,你可以这样做:
def replace_L(match):
return match.group(0).replace(match.group(1),'l'*len(match.group(1)))
string_I_want=re.sub(r'\w+(I+)\w*',replace_L,'I am stiII here.')
您可以使用一个lookaround由另一I
仅更换I
秒,然后或前面:
print re.sub("(?<=I)I|I(?=I)", "l", "I am stiII here.")
基于由DNS提出的答案,我建了一些更复杂的抓住所有的情况下(或至少大多数),尽量不增加太多的错误:
def Irepl(matchobj):
# Catch acronyms
if matchobj.group(0).isupper():
return matchobj.group(0)
else:
# Replace Group2 with 'l's
return matchobj.group(1) + 'l'*len(matchobj.group(2)) + matchobj.group(3)
# Impossible to know if first letter is correct or not (possibly a name)
I_FOR_l_PATTERN = "([a-zA-HJ-Z]+?)(I+)(\w*)"
for line in lines:
tmp_line = line.replace("l'", "I'").replace("'I", "'l").replace(" l ", " I ")
tmp_line = re.sub("^l ", "I ", tmp_line)
cor_line = re.sub(I_FOR_l_PATTERN, Irepl, tmp_line)
# Loop to catch all errors in a word (iIIegaI for example)
while cor_line != tmp_line:
tmp_line = cor_line
cor_line = re.sub(I_FOR_l_PATTERN, Irepl, tmp_line)
希望这有助于有人其他!
你能举出你遇到的其他情况的例子吗? – 2012-03-28 12:10:20