Menemukan kemunculan terakhir substring dalam string, menggantikannya

Jawaban:

163

Ini harus melakukannya

old_string = "this is going to have a full stop. some written sstuff!"
k = old_string.rfind(".")
new_string = old_string[:k] + ". - " + old_string[k+1:]
Aditya Sihag
sumber
1
Terima kasih banyak. Akan harus mempelajari itu sebentar ... ini menggunakan irisan, kan?
Adam Magyar
@AdamMagyar ya, wadah [a: b] irisan dari indeks hingga b-1 wadah. Jika 'a' dihilangkan, maka defaultnya adalah 0; jika 'b' dihilangkan, defaultnya adalah len (container). Operator plus baru saja menggabungkan. Fungsi rfind seperti yang Anda tunjukkan mengembalikan indeks tempat operasi penggantian harus dilakukan.
Aditya Sihag
26

Untuk mengganti dari kanan:

def replace_right(source, target, replacement, replacements=None):
    return replacement.join(source.rsplit(target, replacements))

Digunakan:

>>> replace_right("asd.asd.asd.", ".", ". -", 1)
'asd.asd.asd. -'
Varinder Singh
sumber
1
Saya pasti suka solusi ini tetapi memiliki replacements=Noneparameter sepertinya kesalahan bagi saya karena jika parameter dihilangkan fungsi akan memberikan kesalahan (dicoba dengan Python 2.7). Saya akan menyarankan untuk menghapus nilai default, mengaturnya ke -1 (untuk penggantian tanpa batas) atau lebih baik membuatnya replacements=1(yang menurut saya harus menjadi perilaku default untuk fungsi khusus ini sesuai dengan apa yang diinginkan OP). Menurut dokumen , parameter ini opsional, tetapi harus berupa int jika diberikan.
commentov
Dalam kasus ada yang ingin satu-kapal untuk ini: ". -".join("asd.asd.asd.".rsplit(".", 1)). Yang Anda lakukan adalah melakukan pemisahan string dari sisi kanan untuk 1 kejadian dan menggabungkan string lagi menggunakan penggantinya.
bsplosion
14

Saya akan menggunakan regex:

import re
new_list = [re.sub(r"\.(?=[^.]*$)", r". - ", s) for s in old_list]
Tim Pietzcker
sumber
2
Ini adalah satu-satunya jawaban yang berfungsi jika tidak ada titik sama sekali. Saya akan menggunakan lookahead:\.(?=[^.]*$)
georg
6

Satu baris akan menjadi:

str=str[::-1].replace(".",".-",1)[::-1]

labirin
sumber
1
Ini salah . Anda membalikkan string, menggantinya, lalu membalikkannya kembali. Anda melakukannya .replacedengan string terbalik. Kedua string yang diteruskan replaceharus dibalik juga. Jika tidak, saat Anda membalikkan string untuk kedua kalinya, huruf yang baru saja Anda sisipkan akan terbalik. Anda hanya dapat menggunakan ini jika Anda mengganti satu huruf dengan satu huruf, dan bahkan kemudian saya tidak akan memasukkan ini ke dalam kode Anda jika seseorang harus mengubahnya di masa depan dan mulai bertanya-tanya mengapa ada kata yang ditulis sdrawkcab.
Boris
1

Anda dapat menggunakan fungsi di bawah ini yang menggantikan kemunculan pertama kata dari kanan.

def replace_from_right(text: str, original_text: str, new_text: str) -> str:
    """ Replace first occurrence of original_text by new_text. """
    return text[::-1].replace(original_text[::-1], new_text[::-1], 1)[::-1]
bambuste
sumber
0
a = "A long string with a . in the middle ending with ."

# jika Anda ingin menemukan indeks kemunculan terakhir dari string apa pun, Dalam kasus kami, kami #akan menemukan indeks kemunculan terakhir dengan

index = a.rfind("with") 

# hasilnya akan menjadi 44, karena indeks dimulai dari 0.

Arpan Saini
sumber
-1

Pendekatan naif:

a = "A long string with a . in the middle ending with ."
fchar = '.'
rchar = '. -'
a[::-1].replace(fchar, rchar[::-1], 1)[::-1]

Out[2]: 'A long string with a . in the middle ending with . -'

Jawaban Aditya Sihag dengan satu rfind:

pos = a.rfind('.')
a[:pos] + '. -' + a[pos+1:]
Alex L.
sumber
Ini juga membalikkan string pengganti. Selain itu, ini adalah pengulangan dari jawaban root, dan, seperti yang saya katakan di sana, sangat tidak efisien.
Gareth Latty
@Lattyware Maksud Anda membalikkan a?
Alex L
Maksud saya itu membalikkan '. -'output.
Gareth Latty
Hanya mengharapkan pengguna untuk membalik string literal dengan tangan bukanlah ide yang bagus - itu rentan terhadap kesalahan dan tidak jelas.
Gareth Latty
@Lattyware Setuju. Saya telah membuatnya menjadi var. (Saya menyadari ini adalah metode yang tidak efisien, dan tidak cocok di semua kasus - Anda replace_rightjauh lebih baik)
Alex L