Нахождение последнего вхождения подстроки в строку, замена этого


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
Большое спасибо, чувак. Придется изучить это в течение минуты ... это использование срезов, верно?
— Adam Magyar

@AdamMagyar да, контейнер [a: b] разрезает от a до индекса b-1 контейнера. Если «а» опущено, то по умолчанию используется значение 0; если 'b' опущено, по умолчанию используется len (контейнер). Оператор «плюс» просто объединяется. Функция 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(что, я думаю, должно быть поведением по умолчанию для этой конкретной функции в соответствии с тем, что хочет OP). Согласно документации, этот параметр не является обязательным, но должен быть целым числом, если задан.
— Репликов

В случае , если кто -то хочет Однострочник для этого: ". -".join("asd.asd.asd.".rsplit(".", 1)). Все, что вы делаете, это выполняете разделение строки с правой стороны на 1 вхождение и снова присоединяете строку с помощью замены.
— bsplosion

14

Я бы использовал регулярное выражение:

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

2
Это единственный ответ, который работает, если точки вообще нет. Хотя я бы использовал опережающий \.(?=[^.]*$)
— взгляд

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

Это также меняет местами строку замены. В остальном это повторение ответа root, и, как я там сказал, довольно неэффективно.
— Гарет Латти,

@Lattyware Вы имеете в виду, что это наоборот a?
— Alex L

Я имею в виду, что все наоборот '. -' на выходе на .
— Гарет Латти,

Ожидать, что пользователь перевернет строковый литерал вручную, - не лучшая идея - это чревато ошибками и непонятно.
— Гарет Латти,

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