Знаходження останнього виникнення підрядків у рядку, замінення цього


104

Тож у мене довгий список рядків у тому ж форматі, і я хочу знайти останній "". символу в кожному і замініть його на ". -". Я намагався використовувати rfind, але не можу, як правильно, використовувати це для цього.


Відповіді:


163

Це має робити

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
Велике спасибі людині. Потрібно вивчити це на хвилину ... це використання шматочків, правда?
Адам Мадьяр

@AdamMagyar так, контейнер [a: b] нарізає фрагменти від індексу до b-1. Якщо 'a' пропущено, то він за замовчуванням дорівнює 0; якщо 'b' пропущено, він за замовчуванням лежить (контейнер). Оператор плюс просто об'єднує. Як ви вказали, функція rfind повертає індекс, навколо якого має відбуватися операція заміни.
Адітя Сігаг

26

Щоб замінити справа:

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

У вживанні:

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

1
Мені, безумовно, подобається це рішення, але наявність replacements=Noneпараметра здається мені помилкою, оскільки якщо параметр опущений, функція призведе до помилки (спробували в Python 2.7). Я б запропонував або видалити значення за замовчуванням, встановити його на -1 (для необмеженої заміни) або краще зробити його replacements=1(що, на мою думку, повинно бути поведінкою за замовчуванням для цієї конкретної функції відповідно до того, що хоче ОП). Згідно з документами, цей параметр не є обов'язковим, але він повинен бути цілим, якщо він заданий.
ремарков

У разі , якщо хто -то хоче однострочнікі для цього: ". -".join("asd.asd.asd.".rsplit(".", 1)). Все, що ви робите, - це виконати розділення рядка з правого боку за 1 зустріч і знову приєднатись до рядка, використовуючи заміну.
bsplosion

14

Я б використовував регулярний вираз:

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

2
Це єдина відповідь, яка працює, якщо немає зовсім крапки. Я хотів би скористатися lookahead хоч:\.(?=[^.]*$)
georg

6

Один лайнер буде:

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


1
Це неправильно . Ви обертаєте рядок, замінюєте її, а потім повертаєте її назад. Ви робите .replaceна зворотному рядку. Обидві струни, пропущені, теж replaceповинні бути відмінені. В іншому випадку, коли ви перевернете рядок вдруге, букви, які ви тільки що вставили, будуть назад. Ви можете використовувати це лише в тому випадку, якщо ви замінюєте одну букву однією буквою, і навіть тоді я не ставлю це у вашому коді, якщо хтось повинен її змінити в майбутньому і починає цікавитись, чому слово пишеться sdrawkcab.
Борис

1

Ви можете використовувати функцію, яка нижче замінює перше виникнення слова справа.

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

# якщо ви хочете знайти індекс останнього виникнення будь-якого рядка, у нашому випадку ми знайдемо індекс останнього виникнення з

index = a.rfind("with") 

# результат буде 44, оскільки індекс починається від 0.


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

Відповідь Адітії Сігаг rfind:

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

Це також обертає рядок заміни. Крім цього, це повторення кореневої відповіді, і, як я там кажу, досить неефективно.
Гарет Латті

@Lattyware Ви маєте на увазі, що це обертається назад a?
Алекс Л

Я маю на увазі, що це зворотно '. -'у виході.
Гарет Латті

Просто очікувати, що користувач вручну переверне рядковий літер не є чудовою ідеєю - він схильний до помилок і незрозумілості.
Гарет Латті

@Lattyware Погоджено. Я зробив це вар. (Я розумію, що це неефективний метод, який підходить не у всіх випадках - ваш replace_rightнабагато приємніший)
Alex L
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.