Заменить n-ое вхождение подстроки в строку

Я хочу заменить n-е вхождение подстроки в строку.

Там должно быть что-то эквивалентное тому, что я ХОЧУ сделать, что

mystring.replace("substring", 2nd)

Каков самый простой и самый Pythonic способ достичь этого?

Почему бы не дублировать: я не хочу использовать регулярное выражение для этого подхода, и большинство ответов на подобные вопросы, которые я нашел, – это просто зачистка регулярных выражений или действительно сложная функция. Я действительно хочу как можно проще, а не регулярное решение.

  • График Matplotlib с переменной шириной линии
  • Использование pip за прокси-сервером
  • Anaconda vs miniconda space
  • Почему словарь использует столько ОЗУ в Python
  • Анализ XML SOAP с помощью Python
  • в чем разница между matplotlib.pyplot и matplotlib.figure?
  • Синхронизация даты / времени с сокращенным названием часового пояса в Python?
  • Autobahn отправляет пользовательские и широковещательные сообщения из внешнего приложения
  • 4 Solutions collect form web for “Заменить n-ое вхождение подстроки в строку”

    Вы можете использовать цикл while с str.find чтобы найти n-е вхождение, если оно существует, и использовать эту позицию для создания новой строки:

     def nth_repl(s, sub, repl, nth): find = s.find(sub) # if find is not p1 we have found at least one match for the substring i = find != -1 # loop util we find the nth or we find no match while find != -1 and i != nth: # find + 1 means we start at the last match start index + 1 find = s.find(sub, find + 1) i += 1 # if i is equal to nth we found nth matches so replace if i == nth: return s[:find]+repl+s[find + len(sub):] return s 

    Пример:

     In [14]: s = "foobarfoofoobarbar" In [15]: nth_repl(s, "bar","replaced",3) Out[15]: 'foobarfoofoobarreplaced' In [16]: nth_repl(s, "foo","replaced",3) Out[16]: 'foobarfooreplacedbarbar' In [17]: nth_repl(s, "foo","replaced",5) Out[17]: 'foobarfoofoobarbar' 

    Последний ответ почти идеальный – только одна коррекция:

      def replacenth(string, sub, wanted, n): where = [m.start() for m in re.finditer(sub, string)][n - 1] before = string[:where] after = string[where:] after = after.replace(sub, wanted) newString = before + after return newString 

    Послепорядку необходимо сохранить в этой переменной снова после замены. Спасибо за отличное решение!

    Я придумал ниже, в котором также рассматриваются варианты замены всех «старых» строк влево или вправо. Естественно, нет возможности заменить все вхождения, так как стандартная str.replace отлично работает.

     def nth_replace(string, old, new, n=1, option='only nth'): """ This function replaces occurrences of string 'old' with string 'new'. There are three types of replacement of string 'old': 1) 'only nth' replaces only nth occurrence (default). 2) 'all left' replaces nth occurrence and all occurrences to the left. 3) 'all right' replaces nth occurrence and all occurrences to the right. """ if option == 'only nth': left_join = old right_join = old elif option == 'all left': left_join = new right_join = old elif option == 'all right': left_join = old right_join = new else: print("Invalid option. Please choose from: 'only nth' (default), 'all left' or 'all right'") return None groups = string.split(old) nth_split = [left_join.join(groups[:n]), right_join.join(groups[n:])] return new.join(nth_split) 

    Я использую простую функцию, которая перечисляет все вхождения, выбирает позицию n-го места и использует ее для разделения исходной строки на две подстроки. Затем он заменяет первое вхождение во второй подстроке и присоединяет подстроки обратно к новой строке:

     import re def replacenth(string, sub, wanted, n) where = [m.start() for m in re.finditer(sub, string)][n-1] before = string[:where] after = string[where:] after = after.replace(sub, wanted, 1) newString = before + after print newString 

    Для этих переменных:

     string = 'ababababababababab' sub = 'ab' wanted = 'CD' n = 5 

    выходы:

     ababababCDabababab 

    Заметки:

    where переменная на самом деле представляет собой список позиций спичек, где вы выбираете n-й. Но индекс элемента списка начинается с 0 обычно, а не с 1 . Следовательно, существует индекс n-1 а n – фактическая n-я подстрока. Мой пример находит 5-ю строку. Если вы используете n индекс и хотите найти 5-ю позицию, вам нужно, чтобы n было 4 . Обычно вы используете функцию, которая генерирует наше n .

    Это должен быть самый простой способ, но, возможно, это не самый Pythonic-способ, потому что в конструкции переменной требуется импорт библиотеки. Может быть, кто-то найдет еще более питонический путь.

    Источники и некоторые ссылки дополнительно:

    Python - лучший язык программирования в мире.