मुझे एक ऐसे समाधान की आवश्यकता थी, जहाँ तार को प्रतिस्थापित किया जा सके, एक नियमित अभिव्यक्ति हो सकती है, उदाहरण के लिए किसी एक के साथ कई व्हाट्सएप वर्णों को बदलकर एक लंबे पाठ को सामान्य बनाने में मदद करना। MiniQuark और mmj सहित अन्य लोगों के जवाबों की एक श्रृंखला का निर्माण, यह वही है जिसके साथ मैं आया था:
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)
यह अन्य उत्तरों में दिए गए उदाहरणों के लिए काम करता है, उदाहरण के लिए:
>>> 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.'
मेरे लिए मुख्य बात यह है कि आप नियमित अभिव्यक्ति का उपयोग कर सकते हैं, उदाहरण के लिए केवल पूरे शब्दों को बदलने के लिए, या सफेद स्थान को सामान्य करने के लिए:
>>> 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"
यदि आप सामान्य कुंजी के रूप में शब्दकोश कुंजियों का उपयोग करना चाहते हैं, तो आप इस फ़ंक्शन का उपयोग करते हुए multiple_replace को कॉल करने से पहले बच सकते हैं:
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"
निम्नलिखित फ़ंक्शन आपके शब्दकोश कुंजियों के बीच गलत नियमित अभिव्यक्ति खोजने में मदद कर सकता है (क्योंकि कई से त्रुटि संदेश बहुत अच्छा नहीं है):
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())
ध्यान दें कि यह प्रतिस्थापन की श्रृंखला नहीं करता है, इसके बजाय उन्हें एक साथ करता है। यह विवश किए बिना इसे और अधिक कुशल बनाता है कि यह क्या कर सकता है। चेनिंग के प्रभाव की नकल करने के लिए, आपको बस अधिक स्ट्रिंग-प्रतिस्थापन जोड़े जोड़ने और जोड़े के अपेक्षित क्रम को सुनिश्चित करने की आवश्यकता हो सकती है:
>>> multiple_replace("button", {"but": "mut", "mutton": "lamb"})
'mutton'
>>> multiple_replace("button", [("button", "lamb"),
... ("but", "mut"), ("mutton", "lamb")])
'lamb'