Saya membutuhkan solusi di mana string yang akan diganti dapat berupa ekspresi reguler, misalnya untuk membantu dalam menormalkan teks yang panjang dengan mengganti beberapa karakter spasi putih dengan yang tunggal. Membangun rangkaian jawaban dari orang lain, termasuk MiniQuark dan mmj, inilah yang saya temukan:
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)
Ini berfungsi untuk contoh yang diberikan dalam jawaban lain, misalnya:
>>> 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.'
Hal utama bagi saya adalah Anda dapat menggunakan ekspresi reguler juga, misalnya untuk mengganti seluruh kata saja, atau untuk menormalkan ruang putih:
>>> 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"
Jika Anda ingin menggunakan kunci kamus sebagai string normal, Anda dapat menghindarinya sebelum memanggil multiple_replace menggunakan mis. Fungsi ini:
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"
Fungsi berikut dapat membantu menemukan ekspresi reguler yang salah di antara kunci kamus Anda (karena pesan kesalahan dari multiple_replace tidak terlalu memberi tahu):
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())
Perhatikan bahwa itu tidak mengikat penggantian, melainkan menjalankannya secara bersamaan. Ini membuatnya lebih efisien tanpa membatasi apa yang dapat dilakukan. Untuk meniru efek rantai, Anda mungkin hanya perlu menambahkan lebih banyak pasangan pengganti-string dan memastikan urutan pasangan yang diharapkan:
>>> multiple_replace("button", {"but": "mut", "mutton": "lamb"})
'mutton'
>>> multiple_replace("button", [("button", "lamb"),
... ("but", "mut"), ("mutton", "lamb")])
'lamb'