Değiştirilecek dizelerin düzenli ifadeler olabileceği bir çözüme ihtiyacım vardı, örneğin birden çok boşluk karakterini tek bir karakterle değiştirerek uzun bir metni normalleştirmeye yardımcı olmak için. MiniQuark ve mmj de dahil olmak üzere diğerlerinden gelen bir cevaplar zinciri üzerine inşa ettiğim şey şuydu:
def multiple_replace(string, reps, re_flags = 0):
""" Transforms string, replacing keys from re_str_dict with values.
reps: dictionary, or list of key-value pairs (to enforce ordering;
earlier items have higher priority).
Keys are used as regular expressions.
re_flags: interpretation of regular expressions, such as re.DOTALL
"""
if isinstance(reps, dict):
reps = reps.items()
pattern = re.compile("|".join("(?P<_%d>%s)" % (i, re_str[0])
for i, re_str in enumerate(reps)),
re_flags)
return pattern.sub(lambda x: reps[int(x.lastgroup[1:])][1], string)
Diğer cevaplarda verilen örnekler için çalışır, örneğin:
>>> multiple_replace("(condition1) and --condition2--",
... {"condition1": "", "condition2": "text"})
'() and --text--'
>>> multiple_replace('hello, world', {'hello' : 'goodbye', 'world' : 'earth'})
'goodbye, earth'
>>> multiple_replace("Do you like cafe? No, I prefer tea.",
... {'cafe': 'tea', 'tea': 'cafe', 'like': 'prefer'})
'Do you prefer tea? No, I prefer cafe.'
Benim için asıl önemli olan, düzenli ifadeleri de kullanabilmenizdir, örneğin sadece tüm kelimeleri değiştirmek veya beyaz alanı normalleştirmek için:
>>> s = "I don't want to change this name:\n Philip II of Spain"
>>> re_str_dict = {r'\bI\b': 'You', r'[\n\t ]+': ' '}
>>> multiple_replace(s, re_str_dict)
"You don't want to change this name: Philip II of Spain"
Sözlük tuşlarını normal dizeler olarak kullanmak istiyorsanız, örneğin bu işlevi kullanarak multiple_replace öğesini çağırmadan önce bunlardan kaçabilirsiniz:
def escape_keys(d):
""" transform dictionary d by applying re.escape to the keys """
return dict((re.escape(k), v) for k, v in d.items())
>>> multiple_replace(s, escape_keys(re_str_dict))
"I don't want to change this name:\n Philip II of Spain"
Aşağıdaki işlev, sözlük anahtarlarınız arasında hatalı düzenli ifadeler bulmanıza yardımcı olabilir (multiple_replace hata mesajı çok açık olmadığından):
def check_re_list(re_list):
""" Checks if each regular expression in list is well-formed. """
for i, e in enumerate(re_list):
try:
re.compile(e)
except (TypeError, re.error):
print("Invalid regular expression string "
"at position {}: '{}'".format(i, e))
>>> check_re_list(re_str_dict.keys())
Değiştirmeleri zincirlemediğini, bunun yerine aynı anda gerçekleştirdiğini unutmayın. Bu, yapabileceklerini kısıtlamadan daha verimli hale getirir. Zincirin etkisini taklit etmek için, daha fazla dize değiştirme çifti eklemeniz ve çiftlerin beklenen sırasını sağlamanız gerekebilir:
>>> multiple_replace("button", {"but": "mut", "mutton": "lamb"})
'mutton'
>>> multiple_replace("button", [("button", "lamb"),
... ("but", "mut"), ("mutton", "lamb")])
'lamb'