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


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.