概要
以下のようなテキストが連携されるプログラムがあるとします。
text = "私は今新宿駅。1時間圏内に渋谷駅がある。また、同じ1時間圏内に横浜駅がある。"
ただし、たまに、一文切り落とされ(渋谷駅のパートが削られ)、以下のようにも連携されるとします。
text2 = "私は今新宿駅。また、同じ1時間圏内に横浜駅がある。"
そんな場合に、「また、同じ」のみを削除するにはどうすればいいか?
ちょっと頭使ったので...以下に紹介します。
Pythonのindex
メソッドは、指定した要素がリストや文字列などのイテラブル(反復可能な)オブジェクト内で初めて出現する位置(インデックス)を返します。
以下公式ドキュメントです。
サンプルコード
以下の関数により実現できました。
def replace_phrase_in_text(text, key_word, new_word):
if key_word in text and new_word not in text[:text.index(key_word)]:
text = text.replace(key_word, new_word)
return text
key_word = 'また、同じ1時間圏内に'
new_word = '1時間圏内に'
text = "私は今新宿駅。1時間圏内に渋谷駅がある。また、同じ1時間圏内に横浜駅がある。"
text2 = "私は今新宿駅。また、同じ1時間圏内に横浜駅がある。"
new_text = replace_phrase_in_text(text, key_word, new_word)
print(new_text)
# "私は今新宿駅。1時間圏内に渋谷駅がある。また、同じ1時間圏内に横浜駅がある。"
new_text2 = replace_phrase_in_text(text2, key_word, new_word)
print(new_text2)
# "私は今新宿駅。1時間圏内に横浜駅がある。"
少し分かりづらいですが、分解すると以下の通り。
if key_word in text
は、key_word
がtext
内に存在するかどうかをチェックします。
text.index(key_word)
はkey_word
がtext
内で初めて出現するインデックスを返します。
そして、text[:text.index(key_word)]
はそのインデックスまでのtext
の部分を取得します。
結果として、new_word not in text[:text.index(key_word)]
は、new_word
がtext
の最初からkey_word
が初めて出現するインデックスまでの部分に存在しないかどうかをチェックします。
これらの条件をうまく成立させないと、一つ目のtext
の方で予期せぬカットが発生したりします。
new_word
がtext
の最初からkey_word
が初めて出現するインデックスまでの部分に存在しない場合、というのは、つまり、前半部分の余計な'1時間圏内に'
をカットしないようにするための条件となっています。
find
メソッドについては以前こちらの記事でも紹介したので、ご参考までに。