Menemukan kemunculan terakhir substring dalam string, menggantikannya


104

Jadi saya memiliki daftar panjang string dalam format yang sama, dan saya ingin menemukan "." Yang terakhir. karakter di setiap karakter, dan ganti dengan ". -". Saya sudah mencoba menggunakan rfind, tetapi sepertinya saya tidak dapat menggunakannya dengan benar untuk melakukan ini.


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

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

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]

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]


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]

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.


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

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.