rreplace - Bir dizedeki ifadenin son tekrarlaması nasıl değiştirilir?


139

Python'da dizeleri değiştirmenin hızlı bir yolu var mı, ancak baştan başlamak yerine replacesonuna kadar mı? Örneğin:

>>> 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
İyi bir soru, böylesine basit bir sorunun karmaşık çözümlerine bakarak.
— Justin Ardini

3
Aşağıdaki cevaplarda bu soruya eklenmesi 9 yıl (!) Süren zarif bir astar var, bulmak için aşağı kaydırın.
— John D

Yanıtlar:


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
Çok hoş! Programımdaki tipik bir dizgideki (> 500 karakter) bir ifadenin son tekrarını değiştirmenin bilimsel olmayan bir karşılaştırmasında çözümünüz Alex'in çözümünden üç kat ve Mark'ın çözümünden dört kat daha hızlıydı. Yanıtlarınız için herkese teşekkürler!
— Barthelemy

2
Teşekkürler, işe yarıyor. .replaceYöntem, birinci n oluşumları yerine anlatır üçüncü opsiyonel argüman 'sayısı' alır. Bu -1 gibi bir şey alırsa sezgisel olmaz mıydı ama maalesef olmayacak, bu yüzden çözümünüze ihtiyacımız var.
— kakule

17

Bunu yapmanın en etkili yolu gibi davranmayacağım, ama basit bir yol. Söz konusu tüm dizeleri tersine çevirir str.replace, ters dizeleri kullanarak sıradan bir değiştirme gerçekleştirir , ardından sonucu doğru yönde geri döndürür:

>>> 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

İşte bir astar:

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

Tüm eski dize oluşumları yeni ile değiştirilen dizelerin s kopyasını döndürür . İlk maks . Yer değiştirme olayları değiştirilir.

ve kullanımda bunun tam bir örneği:

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

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

1
Güzel! Sonrasında virgül kaldırmak için kullanılır: line = "".join(line.rsplit(",", 1))daha sonra dolgu alanı tutarken.
— torun

9

Dizeyi tersine çevirin, ilk oluşumu değiştirin ve tekrar ters çevirin:

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)

Çıktı:

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

'Eski' dizenin herhangi bir özel karakter içermediğini biliyorsanız, bunu normal ifadeyle yapabilirsiniz:

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

Sorun için özyinelemeli bir çözüm:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.