有some nice ways来处理python中的同时多字符串替换。但是,我无法创建一个可以做到这一点的高效函数,同时也支持反向引用。Python替换多个字符串,同时支持反向引用
我想要的是使用表达式/替换术语字典,其中替换术语可能包含反向引用到表达式匹配的内容。
例如(注意是\ 1)
repdict = {'&&':'and', '||':'or', '!([a-zA-Z_])':'not \1'}
,我把苏答案在一开始就提到到下面的功能,这对于表达/更换对正常工作不包含反向引用:
def replaceAll(repdict, text):
repdict = dict((re.escape(k), v) for k, v in repdict.items())
pattern = re.compile("|".join(repdict.keys()))
return pattern.sub(lambda m: repdict[re.escape(m.group(0))], text)
然而,它不会为确实包含反向引用的主要工作..
>>> replaceAll(repldict, "!newData.exists() || newData.val().length == 1")
'!newData.exists() or newData.val().length == 1'
如果我做手工,它工作正常。如预期例如: -
pattern = re.compile("!([a-zA-Z_])")
pattern.sub(r'not \1', '!newData.exists()')
作品:
'not newData.exists()'
在花哨的功能,排出似乎搞乱使用了backref的关键,所以它永远不会匹配任何内容。
我终于想出了这个。但是,请注意在输入参数支持backrefs的问题不解决,我只是手动处理它的替代品功能:
def replaceAll(repPat, text):
def replacer(obj):
match = obj.group(0)
# manually deal with exclamation mark match..
if match[:1] == "!": return 'not ' + match[1:]
# here we naively escape the matched pattern into
# the format of our dictionary key
else: return repPat[naive_escaper(match)]
pattern = re.compile("|".join(repPat.keys()))
return pattern.sub(replacer, text)
def naive_escaper(string):
if '=' in string: return string.replace('=', '\=')
elif '|' in string: return string.replace('|', '\|')
else: return string
# manually escaping \ and = works fine
repPat = {'!([a-zA-Z_])':'', '&&':'and', '\|\|':'or', '\=\=\=':'=='}
replaceAll(repPat, "(!this && !that) || !this && foo === bar")
返回:
'(not this and not that) or not this'
因此,如果任何人有一个想法如何制作支持反向引用的多字符串替换函数并接受替换条款作为输入,我非常感谢您的反馈。
为什么不在'replDict'的键中包含任何必要的正则表达式转义,所以你不需要应用're.escape'? – jonrsharpe
这不仅仅是一个转义问题:'!([a-zA-Z])'将匹配'!n',这不是替代字典的关键。您只能使用字典替换固定的字符串。 –
@jonrsharpe谢谢,是的,这就是我最终要做的最后一个例子。但是它非常笨重,例如,一旦匹配成功,我必须将匹配转换为转义匹配(使用naive_escaper),以便我可以在字典中查找替换值(repPat)。我怀疑,也许传递给替代函数的'obj'参数已经在它的内部的某个地方了,所以在几个小时的睡眠之后会进一步探究:-)。 – fzzylogic