2009-06-02 23 views
6

PHP में, आपके पास preg_replace($patterns, $replacements, $string) है, जहां आप पैटर्न और प्रतिस्थापन की एक श्रृंखला में गुजरकर अपने सभी प्रतिस्थापन कर सकते हैं।क्या आप पाइथन में स्ट्रिंग्स को प्रतिस्थापित करते समय एक शब्दकोश को पास कर सकते हैं?

पायथन में समतुल्य क्या है?

मैंने देखा है कि स्ट्रिंग और फिर से कार्यों replace() और sub() शब्दकोशों नहीं लेते हैं ...

संपादित रिक द्वारा एक टिप्पणी के आधार पर स्पष्ट करने के लिए: विचार लिया जाना कुंजी के साथ एक dict है '\d+S' जैसे नियमित अभिव्यक्ति पैटर्न के रूप में, और (उम्मीद है) निरंतर स्ट्रिंग मान (उम्मीद है कि w/o बैक्रेरेंस)। अब तदनुसार मेरा जवाब संपादित करें (यानी वास्तविक प्रश्न का उत्तर देने के लिए)।

उत्तर

10

निकटतम शायद है:

somere.sub(lambda m: replacements[m.group()], text) 
उदाहरण के लिए

:

>>> za = re.compile('z\w') 
>>> za.sub(lambda m: dict(za='BLU', zo='BLA')[m.group()], 'fa za zo bu') 
'fa BLU BLA bu' 
एक .get बजाय [] यदि आप मिलान जो replacements में याद कर रहे हैं के लिए एक डिफ़ॉल्ट की आपूर्ति करना चाहते हैं -indexing साथ

संपादित करें: वास्तव में कौन सी रिक वास्तव में चाहता है कि '\d+S' जैसे नियमित अभिव्यक्ति पैटर्न, और (उम्मीद है) निरंतर स्ट्रिंग मान (उम्मीद है कि w/o बैक्रेरेंस) के रूप में लिया जाना चाहिए। रसोई की किताब नुस्खा इस उद्देश्य के लिए अनुकूलित किया जा सकता है:

def dict_sub(d, text): 
    """ Replace in 'text' non-overlapping occurences of REs whose patterns are keys 
    in dictionary 'd' by corresponding values (which must be constant strings: may 
    have named backreferences but not numeric ones). The keys must not contain 
    anonymous matching-groups. 
    Returns the new string.""" 

    # Create a regular expression from the dictionary keys 
    regex = re.compile("|".join("(%s)" % k for k in d)) 
    # Facilitate lookup from group number to value 
    lookup = dict((i+1, v) for i, v in enumerate(d.itervalues())) 

    # For each match, find which group matched and expand its value 
    return regex.sub(lambda mo: mo.expand(lookup[mo.lastindex]), text) 

उदाहरण उपयोग:

d={'\d+S': 'wot', '\d+T': 'zap'} 
    t='And 23S, and 45T, and 66T but always 029S!' 
    print dict_sub(d, t) 

का उत्सर्जन करता है:

And wot, and zap, and zap but always wot! 

आप lookup और बस mo.expand(d.values()[mo.lastindex-1]) का उपयोग निर्माण से बचने के सकता है, लेकिन है कि हो सकता है d बहुत छोटा है और कई मैचों (माफ करना, दोनों दृष्टिकोणों को सटीक रूप से मापा/बेंचमार्क नहीं किया गया है, इसलिए यह एक छोटा सा धीमा है, इसलिए यह है केवल अनुमान है;-)।

replacements = dict(hello='goodbye', good='bad') 
s = "hello, good morning"; 
for old, new in replacements.items(): 
    s = s.replace(old, new) 

आप कई स्थानों पर जहां पीएचपी कार्यों मूल्यों की एक सरणी स्वीकार करते हैं और कोई प्रत्यक्ष अजगर बराबर है मिलेगा, लेकिन यह बहुत सरणियों के साथ काम करने के लिए आसान है (सूचियां:

+0

यह केवल एक regex का समर्थन करता है हो जाएगा बारे में है, मुझे लगता है कि आप कर सकते हैं अगर आप वास्तव में प्रतिस्थापन और पैटर्न दोनों को चाहते हैं तो एक्टिवस्टेट से पकड़े गए फ़ंक्शन से सरल नहीं होगा। क्या आप? –

+0

एक पास में कई स्ट्रिंग प्रतिस्थापन करने के लिए, मुझे वह नुस्खा पसंद है, इसलिए मैंने इसे पायथन कुकबुक के लिए चुना है, http://books.google.com/books?id=Q0s6Vgb98CQC&pg=PA38&dq=xavier+defrang&ei=k5okSvPbNILClQSk2LWvBw देखें (मुझे लगता है कि चर्चा अन्ना और मैंने कहा कि कुछ मूल्य जोड़ता है, लेकिन मैं निश्चित रूप से पक्षपाती हूं)। मैं पूछे गए सटीक प्रश्न पर अधिक सीधे प्रतिक्रिया देने की कोशिश कर रहा था - एक पूरी तरह से सामान्य आरई और प्रतिस्थापन का एक दिया गया निर्देश। –

+0

मुझे लगता है कि मूल प्रश्न को नुस्खा द्वारा बेहतर उत्तर दिया गया है, क्योंकि PHP की preg_replace दोनों regexps और प्रतिस्थापन स्वीकार करता है। –

-2

यह बहुत आसान यह करने के लिए है) पायथन में तो यह एक मुद्दा से कम है।

+0

आप dict.items के बजाय dict.iteritems का उपयोग करना चाहेंगे, प्रति पीईपी 2 9 0 http://www.python.org/dev/peps/pep- 02 9 0/# लूपिंग-ओवर-डिक्शनरी – NicDumZ

+5

इसे पसंद नहीं है। dict.items() किसी भी विशेष क्रम में होने की गारंटी नहीं है, इसलिए परिणामस्वरूप प्रतिस्थापन अप्रत्याशित है। उदाहरण के लिए, आपके उदाहरण में, यदि "हैलो" पहले संसाधित किया जाता है, परिणामी स्ट्रिंग "खराब, बुरी सुबह" होती है; अन्यथा, यह "अलविदा, बुरी सुबह" है। – Triptych

+0

@Triptych: अच्छा पकड़ो। –

-1

यहाँ कम करने

mynewstring=reduce(lambda a,(b,c): a.replace(b, c), mydict.items(), mystring) 
+0

यह विफल रहता है अगर मेरा नाम '{'a': 'b', 'b': 'a'}' – Eric

+0

@Eric यह एक मूल्य है जिसे हम सरल होने के लिए भुगतान करते हैं। यह सरल तरीका जंजीर प्रतिस्थापन अनुकरण करता है। –

+1

एक साधारण समाधान बेकार है अगर यह – Eric

-2

जबकि अजगर में स्ट्रिंग की जगह आप शब्दकोश पारित कर सकते हैं का उपयोग कर एक सरल तरीका है। पर विचार करें कि ऊपर के उदाहरण:

replacement = {'hello' : 'goodbye', 'good' : 'bad' } 

आप इस प्रारूप में स्ट्रिंग

s = "%(hello)s, %(good)s morning" 
changed_s = s%replacement 

changed_s के उत्पादन

"goodbye, bad morning" 
+1

-1: स्ट्रिंग प्रतिस्थापन नहीं है, इसकी स्ट्रिंग इंटरपोलेशन। – Blair

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

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