rreplace - Làm thế nào để thay thế sự xuất hiện cuối cùng của một biểu thức trong một chuỗi?


139

Có một cách nhanh chóng trong Python để thay thế các chuỗi nhưng, thay vì bắt đầu từ đầu như replacevậy, bắt đầu từ cuối? Ví dụ:

>>> 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
Câu hỏi hay, đánh giá bằng các giải pháp phức tạp cho một vấn đề đơn giản như vậy.
Justin Ardini

3
Có một câu trả lời tao nhã trong các câu trả lời dưới đây mất 9 năm (!) Để được thêm vào câu hỏi này, chỉ cần cuộn xuống để tìm nó.
John D

Câu trả lời:


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
Rất đẹp! Trong một tiêu chuẩn không khoa học về việc thay thế lần xuất hiện cuối cùng của một biểu thức trong một chuỗi điển hình trong chương trình của tôi (> 500 ký tự), giải pháp của bạn nhanh hơn ba lần so với giải pháp của Alex và nhanh hơn bốn lần so với giải pháp của Mark. Cảm ơn tất cả các câu trả lời của bạn!
Barthelemy

2
Cảm ơn, nó hoạt động. Các .replacephương pháp nhận một đối số tùy chọn 'đếm' thứ ba mà nói với nó để thay thế n lần xuất hiện đầu tiên. Nó sẽ không trực quan nếu điều đó sẽ mất -1 like nhưng thật không may, vì vậy chúng tôi cần giải pháp của bạn.
thảo quả

17

Tôi sẽ không giả vờ rằng đây là cách làm hiệu quả nhất, nhưng đó là một cách đơn giản. Nó đảo ngược tất cả các chuỗi trong câu hỏi, thực hiện thay thế thông thường bằng cách sử dụng str.replacetrên các chuỗi đảo ngược, sau đó đảo ngược kết quả trở lại đúng vòng:

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

Đây là một lót:

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

Trả về một bản sao của chuỗi s với tất cả các lần xuất hiện của chuỗi con cũ được thay thế bằng mới . Sự xuất hiện tối đa đầu tiên được thay thế.

và một ví dụ đầy đủ về điều này được sử dụng:

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

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

1
Đẹp! Đã sử dụng nó để xóa dấu phẩy khỏi các dòng: line = "".join(line.rsplit(",", 1))trong khi vẫn giữ không gian đệm sau đó.
cháu

9

Chỉ cần đảo ngược chuỗi, thay thế lần xuất hiện đầu tiên và đảo ngược lại chuỗi:

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)

Đầu ra:

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

Nếu bạn biết rằng chuỗi 'cũ' không chứa bất kỳ ký tự đặc biệt nào, bạn có thể thực hiện nó với biểu thức chính quy:

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

Đây là một giải pháp đệ quy cho vấn đề:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.