2012-02-03 11 views
27

एक regex प्रतिस्थापन कर के लिए, वहाँ तीन चीजें हैं जो आप इसे कर रहे हैं:पायथन में रेगेक्स: क्या मिलान, प्रतिस्थापन और अंतिम स्ट्रिंग प्राप्त करना संभव है?

  • मेल खाने वाला पैटर्न
  • प्रतिस्थापन पैटर्न
  • मूल स्ट्रिंग

वहाँ तीन चीजें हैं जो कर रहे हैं रेगेक्स इंजन पाता है कि मेरे लिए रूचि है:

  • मिलान स्ट्रिंग
  • प्रतिस्थापन स्ट्रिंग
  • अंतिम संसाधित स्ट्रिंग

जब re.sub का उपयोग कर, अंतिम स्ट्रिंग क्या लौटाई गई है। लेकिन क्या यह दो अन्य चीजों, मिलान की गई स्ट्रिंग और प्रतिस्थापन स्ट्रिंग तक पहुंच बनाना संभव है?

orig = "This is the original string." 
matchpat = "(orig.*?l)" 
replacepat = "not the \\1" 

final = re.sub(matchpat, replacepat, orig) 
print(final) 
# This is the not the original string 

मैच स्ट्रिंग "original" है और प्रतिस्थापन स्ट्रिंग "not the original" है:

यहाँ एक उदाहरण है। क्या उन्हें पाने का कोई तरीका है? मैं कई फाइलों में खोजने और बदलने के लिए एक स्क्रिप्ट लिख रहा हूं, और मैं इसे पूरी लाइन को प्रिंट किए बिना इसे ढूंढना और बदलना चाहता हूं।

+0

मैं थोड़ी देर के लिए भी यह सोच रहा हूं। अच्छा प्रश्न! – Blender

+0

बहुत अच्छा सवाल है। और बहुत अच्छी तरह से तैयार किया गया। +1 – ovgolovin

उत्तर

26
class Replacement(object): 

    def __init__(self, replacement): 
     self.replacement = replacement 
     self.matched = None 
     self.replaced = None 

    def __call__(self, match): 
     self.matched = match.group(0) 
     self.replaced = match.expand(self.replacement) 
     return self.replaced 

>>> repl = Replacement('not the \\1') 
>>> re.sub('(orig.*?l)', repl, 'This is the original string.') 
    'This is the not the original string.' 
>>> repl.matched 
    'original' 
>>> repl.replaced 
    'not the original' 

संपादित करें: @FJ के रूप में है इंगित किया गया है, उपर्युक्त केवल अंतिम मैच/प्रतिस्थापन याद रखेगा। यह संस्करण कई घटनाओं को संभालता है:

class Replacement(object): 

    def __init__(self, replacement): 
     self.replacement = replacement 
     self.occurrences = [] 

    def __call__(self, match): 
     matched = match.group(0) 
     replaced = match.expand(self.replacement) 
     self.occurrences.append((matched, replaced)) 
     return replaced 

>>> repl = Replacement('[\\1]') 
>>> re.sub('\s(\d)', repl, '1 2 3') 
    '1[2][3]' 

>>> for matched, replaced in repl.occurrences: 
    ....:  print matched, '=>', replaced 
    ....:  
2 => [2] 
3 => [3] 
+1

+1: मेरे समाधान से काफी अच्छा है। मैं इस कोड को चुरा रहा हूँ। – Blender

+0

यह केवल अंतिम मैच और प्रतिस्थापन को संग्रहीत करेगा, लेकिन उन सभी को रखने के लिए 'मिलान' और 'प्रतिस्थापित' आवृत्ति चर को सूचियों में बदलना मुश्किल नहीं होगा। कॉल करने योग्य वर्ग को पार करने के लिए –

+1

+1 जहां लोग आम तौर पर फ़ंक्शंस का उपयोग करते हैं। चतुर। – twneale

9

मैं प्रलेखन को देखा और जैसे आप re.sub में एक समारोह के संदर्भ पारित कर सकते हैं ऐसा लगता है:

import re 

def re_sub_verbose(pattern, replace, string): 
    def substitute(match): 
    print 'Matched:', match.group(0) 
    print 'Replacing with:', match.expand(replace) 

    return match.expand(replace) 

    result = re.sub(pattern, substitute, string) 
    print 'Final string:', result 

    return result 

और जब re_sub_verbose("(orig.*?l)", "not the \\1", "This is the original string.") चल मैं इस उत्पादन प्राप्त करें:

Matched: original 
Replacing with: not the original 
This is the not the original string. 
+1

+1, मैं उसी चीज को लिखने के बीच में था –

+0

मैं यह समझ नहीं सकता कि इसे कैसे सुंदर बनाना है ताकि यह अन्य regexes के लिए काम करे, क्योंकि मैं इसे अपने कोड में उपयोग कर रहा हूं: पी – Blender

+2

आप 'match.expand (' \\ 1 'नहीं)' (http://docs.python.org/library/re.html#re.MatchObject.expand) को भी कॉल कर सकते हैं –

संबंधित मुद्दे