rreplace - एक स्ट्रिंग में अभिव्यक्ति की अंतिम घटना को कैसे बदलें?


139

क्या पायथन में तारों को बदलने का एक त्वरित तरीका है लेकिन, शुरू से ही शुरू करने के बजाय replace, अंत से शुरू करना है? उदाहरण के लिए:

>>> def rreplace(old, new, occurrence)
>>>     ... # Code to replace the last occurrences of old by new

>>> '<div><div>Hello</div></div>'.rreplace('</div>','</bad>',1)
>>> '<div><div>Hello</div></bad>'

5
अच्छा सवाल, ऐसी सरल समस्या के जटिल समाधानों को देखते हुए।
जस्टिन अर्दिनी

3
नीचे दिए गए उत्तरों में एक सुरुचिपूर्ण एक-लाइनर है जिसे इस प्रश्न में जोड़े जाने में 9 साल (!) लगे, बस इसे खोजने के लिए नीचे स्क्रॉल करें।
जॉन डी

जवाबों:


196
>>> def rreplace(s, old, new, occurrence):
...  li = s.rsplit(old, occurrence)
...  return new.join(li)
... 
>>> s
'1232425'
>>> rreplace(s, '2', ' ', 2)
'123 4 5'
>>> rreplace(s, '2', ' ', 3)
'1 3 4 5'
>>> rreplace(s, '2', ' ', 4)
'1 3 4 5'
>>> rreplace(s, '2', ' ', 0)
'1232425'

9
बहुत अच्छा! मेरे कार्यक्रम (> 500 वर्ण) में एक विशिष्ट स्ट्रिंग में एक अभिव्यक्ति की अंतिम घटना को बदलने के एक अवैज्ञानिक बेंचमार्क में, आपका समाधान एलेक्स के समाधान की तुलना में तीन गुना तेज और मार्क के समाधान की तुलना में चार गुना तेज था। आपके उत्तर के लिए सभी को धन्यवाद!
बर्थेलेमी

2
धन्यवाद, यह काम करता है। .replaceविधि एक तिहाई वैकल्पिक तर्क 'गणना' जो यह बताता है पहले n घटनाओं को बदलने के लिए ले जाता है। क्या यह सहज नहीं होता अगर यह -1 जैसा होता लेकिन दुर्भाग्य से यह नहीं होगा, इसलिए हमें आपके समाधान की आवश्यकता है।
इलायची

17

मैं यह ढोंग करने वाला नहीं हूं कि यह करने का सबसे कुशल तरीका है, लेकिन यह एक सरल तरीका है। यह प्रश्न के सभी तारों str.replaceको उलट देता है, उलटे हुए तारों का उपयोग करके एक साधारण प्रतिस्थापन करता है , फिर परिणाम को सही तरीके से वापस करता है:

>>> def rreplace(s, old, new, count):
...     return (s[::-1].replace(old[::-1], new[::-1], count))[::-1]
...
>>> rreplace('<div><div>Hello</div></div>', '</div>', '</bad>', 1)
'<div><div>Hello</div></bad>'

10

यहाँ एक लाइनर है:

result = new.join(s.rsplit(old, maxreplace))

स्ट्रिंग की एक प्रति लौटें रों सबस्ट्रिंग की सभी घटनाओं के साथ वर्ष के द्वारा बदल दिया नया । पहली अधिकतम सीमाएँ प्रतिस्थापित होती हैं।

और उपयोग में इसका एक पूर्ण उदाहरण:

s = 'mississipi'
old = 'iss'
new = 'XXX'
maxreplace = 1

result = new.join(s.rsplit(old, maxreplace))
>>> result
'missXXXipi'

1
अच्छा! इसका उपयोग लाइनों से ट्रेलिंग कॉमा को हटाने के लिए किया जाता है: line = "".join(line.rsplit(",", 1))बाद में पैडिंग स्पेस रखते हुए।
पोती

9

बस स्ट्रिंग को उल्टा करें, पहली घटना को बदलें और इसे फिर से उल्टा करें:

mystr = "Remove last occurrence of a BAD word. This is a last BAD word."

removal = "BAD"
reverse_removal = removal[::-1]

replacement = "GOOD"
reverse_replacement = replacement[::-1]

newstr = mystr[::-1].replace(reverse_removal, reverse_replacement, 1)[::-1]
print ("mystr:", mystr)
print ("newstr:", newstr)

आउटपुट:

mystr: Remove last occurence of a BAD word. This is a last BAD word.
newstr: Remove last occurence of a BAD word. This is a last GOOD word.

5

यदि आप जानते हैं कि 'पुराने' स्ट्रिंग में कोई विशेष वर्ण नहीं है, तो आप इसे रेगेक्स के साथ कर सकते हैं:

In [44]: s = '<div><div>Hello</div></div>'

In [45]: import re

In [46]: re.sub(r'(.*)</div>', r'\1</bad>', s)
Out[46]: '<div><div>Hello</div></bad>'

1

यहाँ समस्या का एक पुनरावर्ती समाधान है:

def rreplace(s, old, new, occurence = 1):

    if occurence == 0:
        return s

    left, found, right = s.rpartition(old)

    if found == "":
        return right
    else:
        return rreplace(left, old, new, occurence - 1) + new + right
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.