【Python】一番最後に出現する文字のみを置換する方法

本記事では特定の文字を検索し,一番最後にヒットした文字列を置換する方法をご紹介します.

事前準備

今回は正規表現を使用するのでPythonの標準ライブラリのreimportします.
また,置換対象の文章も合わせて変数に入れておきます.


import re

s = '''吾輩は猫である。名前はまだ無い。〜中略〜 吾輩はここで始めて人間というものを見た。
〜中略〜 はてな何でも容子がおかしいと、のそのそ這い出して見ると非常に痛い。
吾輩は藁わらの上から急に笹原の中へ棄てられたのである。
'''

一番最後にヒットした文字列のみを置換

事前準備で用意した文章には「吾輩」という言葉が複数出現しています.
この「吾輩」のうち,一番最後にヒットする「吾輩」のみを任意の文字列に変換します.


ss = re.sub(r'吾輩(?!.+吾輩)', '★★', s, flags=re.DOTALL)
print(ss)
吾輩は猫である。名前はまだ無い。〜中略〜 吾輩はここで始めて人間というものを見た。
〜中略〜 はてな何でも容子がおかしいと、のそのそ這い出して見ると非常に痛い。
★★は藁わらの上から急に笹原の中へ棄てられたのである。

※ 実行結果の色は見やすさのためにつけています.

結果を見ると最後に出現した「吾輩」のみが「★★」になっていますね.

また,「吾輩」の出現数が1つだけ減っているのも以下で確認できます.


print(f'置換前の吾輩の数{s.count("吾輩")}')
print(f'置換後の吾輩の数{ss.count("吾輩")}')
置換前の吾輩の数3
置換後の吾輩の数2

解説

正規表現の否定先読みを使用して「吾輩」とマッチし,その後「吾輩」で終わることがなければマッチした「吾輩」を置換するということをしています.

sub()の引数については以下のとおりです.

  • 第一引数:正規表現を指定します.1
  • 第二引数:置換後の文字列を指定します.
  • 第三引数:置換対象の文字列を指定します.
  • 第四引数:.を改行にもマッチさせるためのフラグ指定です.2

行単位で最後の文字列のみを置換

行単位で最後に出現する文字を置換する場合は以下のようなコードです.


sss = re.sub(r'吾輩(?!.+吾輩)', '★★', s)
print(sss)
吾輩は猫である。名前はまだ無い。〜中略〜 ★★はここで始めて人間というものを見た。
〜中略〜 はてな何でも容子がおかしいと、のそのそ這い出して見ると非常に痛い。
★★は藁わらの上から急に笹原の中へ棄てられたのである。

※ 実行結果の色は見やすさのためにつけています.

前項のコードからflags=re.DOTALLを除いただけです.
これにより改行を含む単位で最後に出現する「吾輩」を判定するようになります.3

ひとこと

もっとよい方法をご存知の方がいればぜひお知らせください.


  1. rはraw文字列を指定しています. 

  2. このフラグがない場合,.が改行でマッチしなくなります.フラグを付けない場合の検証は事項参照. 

  3. 結果を見ると「吾輩」が含まれる1, 3行目について,最後の「吾輩」が「★★」に置換されています.