2010-03-31 56 views
72

Có cách nào nhanh chóng trong Python để thay thế chuỗi nhưng, thay vì bắt đầu từ đầu như replace, bắt đầu từ kết thúc? Ví dụ: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?

>>> 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>' 
+3

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

Trả lời

112
>>> 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' 
+0

+1 Tôi nghĩ rằng điều này cũng sẽ khá nhanh. –

+6

Rất đẹp! Trong một tiêu chuẩn không khoa học thay thế sự 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 gấp ba lần so với giải pháp của Alex và bốn lần nhanh hơn giải pháp của Mark. Cảm ơn tất cả vì câu trả lời của bạn! – Barthelemy

+0

cảm ơn kết quả điểm chuẩn –

7

Tôi sẽ không giả vờ rằng đây là cách hiệu quả nhất để làm điều đó, 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 một sự thay thế thông thường sử dụng str.replace trên chuỗi đảo ngược, sau đó đảo ngược kết quả trở lại đúng cách tròn:

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

Dưới đâ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 
3

Nếu bạn biết rằng chuỗi 'cũ' không chứa bất kỳ ký tự đặc biệt bạn có thể làm điều đó với một regex:

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>' 
Các vấn đề liên quan