Znalezienie ostatniego wystąpienia podciągu w ciągu znaków, zastąpienie go
104
Mam więc długą listę ciągów w tym samym formacie i chcę znaleźć ostatni „”. znak w każdym z nich i zamień go na „. -”. Próbowałem użyć rfind, ale nie mogę go właściwie wykorzystać, aby to zrobić.
Wielkie dzięki stary. Będę musiał się temu uczyć przez minutę ... to jest użycie plasterków, prawda?
Adam Magyar
@AdamMagyar tak, kontener [a: b] wycina od a do b-1 indeksu kontenera. Jeśli pominięto „a”, przyjmuje wartość domyślną 0; jeśli pominięto „b”, domyślnie len (kontener). Operator plusa po prostu konkatenuje. Funkcja rfind, jak wskazałeś, zwraca indeks, wokół którego powinna mieć miejsce operacja zamiany.
Zdecydowanie podoba mi się to rozwiązanie, ale posiadanie replacements=Noneparametru wydaje mi się błędem, ponieważ jeśli parametr zostanie pominięty, funkcja spowoduje błąd (próbowano w Pythonie 2.7). Sugerowałbym albo usunięcie wartości domyślnej, ustawienie jej na -1 (dla nieograniczonej liczby wymian) lub lepsze jej wykonanie replacements=1(co moim zdaniem powinno być domyślnym zachowaniem dla tej konkretnej funkcji zgodnie z tym, czego chce PO). Zgodnie z dokumentacją ten parametr jest opcjonalny, ale jeśli został podany, musi to być wartość int.
remarkov
W przypadku, gdy ktoś chce mieć jedną wkładkę na to: ". -".join("asd.asd.asd.".rsplit(".", 1)). Wszystko, co robisz, to rozdzielenie ciągu z prawej strony na jedno wystąpienie i ponowne połączenie łańcucha za pomocą zamiany.
bsplosion
14
Użyłbym wyrażenia regularnego:
import re
new_list =[re.sub(r"\.(?=[^.]*$)", r". - ", s)for s in old_list]
To jest złe . Odwracasz strunę, zastępujesz ją, a następnie cofasz z powrotem. Robisz .replacena odwróconej strunie. Oba przekazane ciągi również replacemuszą zostać odwrócone. W przeciwnym razie, gdy odwrócisz ciąg po raz drugi, wstawione litery będą odwrócone. Możesz tego użyć tylko wtedy, gdy zastępujesz jedną literę jedną literą, a nawet wtedy nie umieściłbym tego w twoim kodzie, gdyby ktoś musiał to zmienić w przyszłości i zaczął się zastanawiać, dlaczego słowo jest napisane sdrawkcab.
Boris
1
Możesz użyć poniższej funkcji, która zastępuje pierwsze wystąpienie słowa od prawej.
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]
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 . -'
To również odwraca ciąg zastępczy. Poza tym jest to powtórzenie odpowiedzi roota i, jak tam powiedziałem, dość nieefektywne.
Gareth Latty
@Lattyware Masz na myśli odwrócenie a?
Alex L
Mam na myśli to, że odwraca się '. -'na wyjściu.
Gareth Latty
Samo oczekiwanie, że użytkownik ręcznie odwróci literał ciągu, nie jest dobrym pomysłem - jest podatny na błędy i niejasny.
Gareth Latty
@ Lattyware Agreed. Zrobiłem to var. (Zdaję sobie sprawę, że jest to nieefektywna metoda i nie jest odpowiednia we wszystkich przypadkach - twoja replace_rightjest o wiele przyjemniejsza)
Odpowiedzi:
To powinno wystarczyć
źródło
Aby wymienić od prawej:
W użyciu:
źródło
replacements=None
parametru wydaje mi się błędem, ponieważ jeśli parametr zostanie pominięty, funkcja spowoduje błąd (próbowano w Pythonie 2.7). Sugerowałbym albo usunięcie wartości domyślnej, ustawienie jej na -1 (dla nieograniczonej liczby wymian) lub lepsze jej wykonaniereplacements=1
(co moim zdaniem powinno być domyślnym zachowaniem dla tej konkretnej funkcji zgodnie z tym, czego chce PO). Zgodnie z dokumentacją ten parametr jest opcjonalny, ale jeśli został podany, musi to być wartość int.". -".join("asd.asd.asd.".rsplit(".", 1))
. Wszystko, co robisz, to rozdzielenie ciągu z prawej strony na jedno wystąpienie i ponowne połączenie łańcucha za pomocą zamiany.Użyłbym wyrażenia regularnego:
źródło
\.(?=[^.]*$)
Jedna linijka to:
str=str[::-1].replace(".",".-",1)[::-1]
źródło
.replace
na odwróconej strunie. Oba przekazane ciągi równieżreplace
muszą zostać odwrócone. W przeciwnym razie, gdy odwrócisz ciąg po raz drugi, wstawione litery będą odwrócone. Możesz tego użyć tylko wtedy, gdy zastępujesz jedną literę jedną literą, a nawet wtedy nie umieściłbym tego w twoim kodzie, gdyby ktoś musiał to zmienić w przyszłości i zaczął się zastanawiać, dlaczego słowo jest napisane sdrawkcab.Możesz użyć poniższej funkcji, która zastępuje pierwsze wystąpienie słowa od prawej.
źródło
# jeśli chcesz znaleźć indeks ostatniego wystąpienia dowolnego ciągu, w naszym przypadku # znajdziemy indeks ostatniego wystąpienia z
# wynikiem będzie 44, ponieważ indeks zaczyna się od 0.
źródło
Naiwne podejście:
Odpowiedź Adityi Sihag z jednym
rfind
:źródło
a
?'. -'
na wyjściu.replace_right
jest o wiele przyjemniejsza)