🐍

Pythonで、正規表現でn番目にmatchした部分文字列だけを置換する

2022/06/05に公開

概要

あるstrのうち、特定の文字列にマッチする部分を別の文字列に置換することを考える。

pythonのstr.replace()にはcount引数があり、置換回数を指定することができる。
https://note.nkmk.me/python-str-replace-translate-re-sub/

これだとn番目「まで」が置換されるので、n番目だけを置換したい場合は別の方法が必要である。
https://teratail.com/questions/222949

では、特定の文字列ではなく正規表現に対して、n番目にマッチする部分のみを置換するにはどうしたらよいか。

考察

re.findall()[n]で置換したい部分の文字列を取り出したとして、被りがあった場合に特定できなくなってしまう。
今回はre.finditerで位置を取り出し、分割→結合するアプローチをとる。。

実装

文字列sの中でn番目にpatternにマッチする箇所をtに置換する。

replace_nth.py
def replace_nth(pattern, t, s, n):
    """
    replace substring of s, nth matching pattern, to t
    @param pattern: regular expression
    @param t: string
    @param s: string
    @param n: int
    @return: string
    """
    match_itrs = re.finditer(pattern, s)
    cnt = 0
    dst = s
    for itr in match_itrs:
        span = itr.span()
        if cnt == n:
            dst = s[:span[0]] + t + s[span[1]:]
        cnt += 1
    return dst

まとめ

  • イテレータの使い方には注意(色々考えて結局for文を回した)
  • 次はrepl関数を与えられるようにしたい

Discussion