Dize içindeki son alt dizeyi bulma, onu değiştirme


Yanıtlar:


163

Bu yapmalı

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
Çok teşekkürler dostum. Bunu bir dakikalığına incelemek zorunda kalacak ... bu dilimleri kullanıyor, değil mi?
Adam Magyar

@AdamMagyar evet, container [a: b], kabın bir b-1 indeksinden dilimler. 'A' atlanırsa, varsayılan olarak 0; 'b' atlanırsa, varsayılan olarak len (kapsayıcı) olur. Artı operatörü sadece bitiştirir. Belirttiğiniz gibi rfind işlevi, değiştirme işleminin etrafında gerçekleşmesi gereken dizini döndürür.
Aditya Sihag

26

Sağdan değiştirmek için:

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

Kullanımda:

>>> replace_right("asd.asd.asd.", ".", ". -", 1)
'asd.asd.asd. -'

1
Bu çözümü kesinlikle beğendim, ancak replacements=Noneparametreye sahip olmak bana bir hata gibi görünüyor çünkü parametre atlanırsa işlev bir hata verecektir (Python 2.7'de denendi). Ya varsayılan değeri kaldırmanızı, -1 olarak ayarlamanızı (sınırsız değiştirme için) ya da daha iyi hale getirmenizi öneririm replacements=1(ki bu, OP'nin istediği şeye göre bu belirli işlev için varsayılan davranış olmalıdır). Dokümanlara göre bu parametre isteğe bağlıdır, ancak verilmişse bir int olmalıdır.
2016, 08:05

Durumda herkes bunun için bir tek astar istiyor: ". -".join("asd.asd.asd.".rsplit(".", 1)). Yaptığınız tek şey, 1 kez sağ taraftan bir dizi ayırma gerçekleştirmek ve değiştirmeyi kullanarak dizeyi tekrar birleştirmektir.
bsplosion

14

Bir normal ifade kullanırdım:

import re
new_list = [re.sub(r"\.(?=[^.]*$)", r". - ", s) for s in old_list]

2
Hiç nokta yoksa işe yarayan tek cevap budur. Yine de bir bakış kullanırım:\.(?=[^.]*$)
georg

6

Bir tek satırlık:

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


1
Bu yanlış . Dizeyi ters çeviriyorsunuz, değiştiriyorsunuz ve sonra geri çeviriyorsunuz. .replaceTers bir ip üzerinde yapıyorsun . Her iki dizenin replacede tersine çevrilmesi gerekiyordu. Aksi takdirde, dizeyi ikinci kez ters çevirdiğinizde, eklediğiniz harfler geriye doğru olacaktır. Bunu yalnızca bir harfi tek bir harfle değiştiriyorsanız kullanabilirsiniz ve o zaman bile bunu kodunuza koymam, çünkü gelecekte birisinin onu değiştirmesi ve bir kelimenin neden sdrawkcab yazıldığını merak etmeye başlaması.
Boris

1

Sağdan kelimenin ilk geçtiği yeri değiştiren aşağıdaki işlevi kullanabilirsiniz.

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

# herhangi bir dizenin son oluşumunun dizinini bulmak istiyorsanız, bizim durumumuzda # ile son oluşumunun dizinini bulacağız

index = a.rfind("with") 

# dizin 0'dan başladığından sonuç 44 olacaktır.


-1

Naif yaklaşım:

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

Aditya Sihag'ın tek bir cevabı rfind:

pos = a.rfind('.')
a[:pos] + '. -' + a[pos+1:]

Bu, değiştirme dizesini de tersine çevirir. Bunun dışında, kök yanıtının tekrarı ve orada söylediğim gibi, oldukça verimsiz.
Gareth Latty

@Lattyware Tersine ami dönüyor ?
Alex L

Demek istediğim '. -'çıktıda tersine dönüyor .
Gareth Latty

Sadece kullanıcının dizgiyi elle tersine çevirmesini beklemek harika bir fikir değildir - hatalara meyillidir ve belirsizdir.
Gareth Latty

@Lattyware Kabul Edildi. Bunu bir değişken yaptım. (Bunun verimsiz bir yöntem olduğunun ve her durumda uygun olmadığının farkındayım - replace_rightçok daha hoş)
Alex L
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.