LoginSignup
0
0

More than 1 year has passed since last update.

Pythonで正規表現にマッチした文字列をひとつずつ置換する方法

Last updated at Posted at 2023-03-07

やりたいこと

  • あるテキストの中で、正規表現にマッチした文字列をその内容に基づいて一つずつ置換し、その置換後のテキストを得たい。
  • 簡単な例
    • もとのテキスト: aaa <<hoge>> bbb <<fuga>> ccc <<hoge>>
    • 置換方法:
      • <<hoge>> => APPLE
      • <<fuga>> => BANANA
    • 得たいテキスト: aaa APPLE bbb BANANA ccc APPLE

実装

追記:コメントをいただき、 re.sub() で簡単に実装できることがわかったので、修正しました。コメントをくださった方、ありがとうございます!

import re


def my_replace(match):
    """マッチした文字列に基づいて置換後の文字列を返却する。"""
    return "APPLE" if match[0] == "<<hoge>>" else "BANANA"


input_text = "aaa <<hoge>> bbb <<fuga>> ccc <<hoge>>"
result_text = re.sub(r"<<.+?>>", my_replace, input_text)

assert result_text == "aaa APPLE bbb BANANA ccc APPLE"
もともとの実装
import re


def my_replace(match_str):
    """マッチした文字列に基づいて置換後の文字列を返却する。"""
    key = match_str[2:-2]
    if key == "hoge":
        return "APPLE"
    return "BANANA"


# 置換したい文字列の正規表現
pattern = re.compile(r"(<<.+?>>)")
# もとのテキスト
input_text = "aaa <<hoge>> bbb <<fuga>> ccc <<hoge>>"
# 得たいテキスト(を格納するための変数)
result_text = ""

# 置換処理(やっていることはシンプルで、マッチした文字列をひとつずつ置換しながら、もとのテキストを連結している)
last_end = 0
for m in re.finditer(pattern, input_text):
    result_text += input_text[last_end:m.start()]
    result_text += my_replace(m.group())
    last_end = m.end()

result_text += input_text[last_end:]

# 結果
assert result_text == "aaa APPLE bbb BANANA ccc APPLE"

備考

  • 単に正規表現にマッチした文字列を一括で置換するだけなら .replace()re.sub() を使えばOKなのだが、 マッチした文字列の内容に応じて置換後の文字列を変更したい というようなケースでは、 .replace()re.sub() を用いるのは難しい。
    • (上記「簡単な例」なら .replace("<<hoge>>", "APPLE").replace("<<fuga>>", "BANANA") でも実現可能なのだが、あくまで「簡単な例」なので・・・。)
  • 追記: re.sub() は第2引数に文字列だけでなく関数も取ることができるので、それで実現可能。

参考サイト

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0