python - पायथन में रेगेक्स का उपयोग करके मैं एकाधिक प्रतिस्थापन कैसे कर सकता हूं?




regex string (3)

@Nhahtdh द्वारा प्रस्तावित उत्तर मान्य है, लेकिन मैं कैनोलिक उदाहरण से कम पायथनिक तर्क दूंगा, जो कोड को अपने रेगेक्स मैनिपुलेशन से कम अपारदर्शी का उपयोग करता है और पाइथन के अंतर्निहित डेटा संरचनाओं और अज्ञात फ़ंक्शन सुविधा का लाभ उठाता है।

अनुवादों का एक शब्दकोश इस संदर्भ में समझ में आता है। वास्तव में, इस उदाहरण में दिखाया गया है कि पाइथन कुकबुक यह करता है (ActiveState http://code.activestate.com/recipes/81330-single-pass-multiple-replace/ ) से कॉपी किया गया है

import re 

def multiple_replace(dict, text):
  # Create a regular expression  from the dictionary keys
  regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))

  # For each match, look-up corresponding value in dictionary
  return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text) 

if __name__ == "__main__": 

  text = "Larry Wall is the creator of Perl"

  dict = {
    "Larry Wall" : "Guido van Rossum",
    "creator" : "Benevolent Dictator for Life",
    "Perl" : "Python",
  } 

  print multiple_replace(dict, text)

तो आपके मामले में, आप एक dict trans = {"a": "aa", "b": "bb"} और उसके बाद इसे अनुवादित पाठ के साथ multiple_replace में पास कर सकते हैं। असल में यह सब काम कर रहा है, अनुवाद के लिए अपने सभी regexes युक्त एक विशाल regex बना रहा है, तो जब कोई पाया जाता है, अनुवाद शब्द लुकअप करने के लिए regex.sub करने के लिए एक lambda समारोह गुजर रहा है।

आप अपनी फ़ाइल से पढ़ने के दौरान इस फ़ंक्शन का उपयोग कर सकते हैं, उदाहरण के लिए:

with open("notes.txt") as text:
    new_text = multiple_replace(replacements, text.read())
with open("notes2.txt", "w") as result:
    result.write(new_text)

मैंने वास्तव में उत्पादन में इस सटीक विधि का उपयोग किया है, ऐसे मामले में जहां मुझे वेब स्क्रैपिंग कार्य के लिए वर्ष के महीनों का अनुवाद चेक से अंग्रेजी में करना था।

जैसा कि @nhahtdh ने इंगित किया है, इस दृष्टिकोण के लिए एक नकारात्मक पक्ष यह है कि यह उपसर्ग मुक्त नहीं है: शब्दकोश कुंजी जो अन्य शब्दकोश कुंजी के उपसर्ग हैं, विधि को तोड़ने का कारण बनेंगे।

https://code.i-harness.com

मैं नियमित अभिव्यक्तियों का उपयोग करके a के प्रतिस्थापन के साथ एक नई फ़ाइल बनाने के लिए नीचे इस कोड का उपयोग कर सकता हूं।

import re

with open("notes.txt") as text:
    new_text = re.sub("a", "aa", text.read())
    with open("notes2.txt", "w") as result:
        result.write(new_text)

मैं सोच रहा था कि मुझे इस लाइन का उपयोग करना है, new_text = re.sub("a", "aa", text.read()) , कई बार लेकिन अन्य अक्षरों के लिए स्ट्रिंग को प्रतिस्थापित करें जिन्हें मैं बदलने के लिए बदलना चाहता हूं मेरे पाठ में एक से अधिक पत्र?

यही है, तो a -> b , b -> bb और c -> cc

तो मुझे उन सभी अक्षरों के लिए उस पंक्ति को लिखना है जिन्हें मैं बदलना चाहता हूं या क्या कोई आसान तरीका है। शायद अनुवादों का एक "शब्दकोश" बनाना है। क्या मुझे उन अक्षरों को सरणी में रखना चाहिए? मुझे यकीन नहीं है कि अगर मैं करता हूं तो उन पर कैसे कॉल करें।


आप कैप्चरिंग समूह और बैकरेफर का उपयोग कर सकते हैं:

re.sub(r"([characters])", r"\1\1", text.read())

उन अक्षरों को रखें जिन्हें आप [] बीच में दोगुना करना चाहते हैं। निचले मामले के मामले में a , b , c :

re.sub(r"([abc])", r"\1\1", text.read())

प्रतिस्थापन स्ट्रिंग में, आप किसी भी कैप्चरिंग समूह () साथ मिलान किए गए किसी भी संदर्भ को संदर्भित कर सकते हैं जहां n कुछ सकारात्मक पूर्णांक (0 को छोड़कर) है। \1 पहले कैप्चरिंग समूह को संदर्भित करता है। एक और नोटेशन \g<n> जहां n कोई गैर-ऋणात्मक पूर्णांक हो सकता है (0 अनुमत); \g<0> अभिव्यक्ति से मिलान किए गए पूरे पाठ का संदर्भ लेंगे।

यदि आप नई पंक्ति को छोड़कर सभी पात्रों को दोगुना करना चाहते हैं:

re.sub(r"(.)", r"\1\1", text.read())

यदि आप सभी पात्रों को डबल करना चाहते हैं (नई लाइन शामिल):

re.sub(r"(.)", r"\1\1", text.read(), 0, re.S)

एक ' स्ट्रिंग ' वर्ग बनाने के सुझावों का उपयोग करके, हम एक ऑब्जेक्ट को एक स्ट्रिंग के समान बना सकते हैं लेकिन अतिरिक्त sub विधि के लिए:

import re
class Substitutable(str):
  def __new__(cls, *args, **kwargs):
    newobj = str.__new__(cls, *args, **kwargs)
    newobj.sub = lambda fro,to: Substitutable(re.sub(fro, to, newobj))
    return newobj

यह बिल्डर पैटर्न का उपयोग करने की अनुमति देता है, जो कि अच्छा दिखता है, लेकिन केवल पूर्व निर्धारित संख्याओं के लिए काम करता है। यदि आप इसे लूप में उपयोग करते हैं, तो अब कोई अतिरिक्त कक्षा बनाने का कोई मतलब नहीं है। उदाहरण के लिए

>>> h = Substitutable('horse')
>>> h
'horse'
>>> h.sub('h', 'f')
'forse'
>>> h.sub('h', 'f').sub('f','h')
'horse'




string