Pythonのreplace()は、文字列を置換することができる文字列メソッドです。ここでは、このメソッドについて解説します。
なお、reモジュールのsub関数というものにも触れますが、これは、正規表現というものを使って、replaceメソッドより高度な置換を行うためのものです。まずはreplaceメソッドをしっかりと学習して、その後、必要が出てきたときにsub関数を学習すると良いでしょう。
なお『Pythonの文字列置換まとめ|replace, translate, re.sub, スライス』では、ここで解説する方法以外の文字列置換も扱っていますので、ぜひあわせてご覧いただければと思います。
1. Pythonのreplaceメソッドの使い方
replaceメソッドは、文字列の中のある文字を、任意の文字に置換して、新しい文字列を作るメソッドです。基本書式は次の通りです。
文字列.replace(置換したい文字, 新しい文字, 置換回数)
置換したい文字には、その名の通り変更したい文字を入力します。新しい文字には、新しく入れ替えたい文字を入力ます。置換回数には、「置換したい文字列」が複数あるとして、それを何個入れ替えたいかを数字で入力します。
実際に見ていきましょう。
1.1. replaceメソッドの基本の使い方
次の例では、 ‘an apple’ を ‘a banana’ に置換しています。
text = "I like an apple"
#appleをbananaに置換します。
new_text = text.replace("an apple", "a banana")
print(new_text)
replace()の第一引数に置換したい文字である’an apple’を、第二引数に新しく入れ替える文字である’a banana’を渡しています。出力結果を見るとその通り置換されていますね。
replaceメソッドは「置換したい文字」に該当する文字が複数ある場合、それを全て置換します。
以下をご覧ください。
text = 'Aだ。Bだ。'
# 語尾を「です」に変えます。
new_text = text.replace('だ', 'です')
print(new_text)
二つの「だ」が、どちらも一度に「です」に変わっていますね。
1.2. replaceメソッドの2つの注意点
このように文字列の置換に便利なreplaceメソッドですが、注意点もあります。
1.2.1. 文字列をシーケンス(連なり)として認識する
まずは次の例をご覧ください。
text = "This is what is wanted to change this world"
#isをwasに置換します。
new_text = text.replace("is", "was")
print(new_text)
“is” を “was”に置換したいだけだったのですが、”This”と”this”の中に入っている”is”も置換されて、めちゃくちゃな文字になってしまいました。
replaceメソッドは、文字列を個別の意味を持つ単語として認識しているのではなく、1文字ずつの連なり(=シーケンス)として見ています。そのため、第一引数に渡した置換したい文字と同じ並びの文字があれば、全て置換してしまいます。
1.2.2. 大文字と小文字は別の文字として認識する
Pythonではアルファベットの大文字と小文字は別の文字として認識されます。repalceメソッドでも同様です。
以下をご覧ください。
text = "abc"
#bを大文字にします。
new_text = text.replace("b", "B")
print(new_text)
小文字のbが大文字のBに変わりましたね。
もう一つ見ておきましょう。
song = "Let it be, let it be, let it be"
#大文字と小文字は区別されます。
new_song = song.replace("let", "don't let")
print(new_song)
“let”を”don’t let”に置換しています。最初の”Let”の”L”は大文字なので、小文字の”let”とは別物と判断されて置換されません。
1.3. 第三引数で置換回数を指定する
もし、「置換したい文字列」に一致する全ての文字列を変換したくないという場合は、置換回数を指定することで対応します。
以下をご覧ください。
text = 'Aだ。Bだ。'
# 語尾を「です」に変えます。
new_text = text.replace('だ', 'です', 1)
print(new_text)
置換回数1回と指定しているので、最初の「だ」だけ「です」に置換されます。
1.4. 置換したい文字が複数ある場合
Pythonのreplace()で複数の「置換したい文字」がある場合は、replace()の重ねがけをすることで実現できます。
1.4.1. replaceメソッドの重ねがけで複数の文字を置換する
例えば、次のコードでは重ねがけをして、「となります」と「だ」を「です」に置換しています。
'''replaceメソッドを重ねて使うと複数の文字を置換することができます。 '''
text = 'これは文字列となります。つまりstr型オブジェクトだ。'
print(text)
print(text.replace('となります', 'です').replace('だ', 'です'))
ただし、この方法で改行コードの置換を行うときは注意が必要です。
1.4.2. replace()で改行コードを置換する時は要注意
次のコードは、複数の改行コードが入り乱れている短歌から、改行コード(\nと\r\n)を、replaceの重ねがけで ”(クオートの中に何もないもの)と置換しているものです。
''' 改行コードが入り乱れていても一度に置換(削除)できます。 '''
tanka = 'ふるさとの\r\n山に向ひて\n言ふことなし\r\nふるさとの山は\nありがたきかな'
print(tanka)
print('\n') # ←見やすいように改行を入れています。
print(tanka.replace('\r\n', '').replace('\n', ''))
これだとうまく言っていますね。しかし、replaceの重ねがけの順番を間違うと、全く意図しない結果になってしまいます。
''' しかし順番を間違えると意図せぬ結果になってしまいます。 '''
print(tanka.replace('\n', '').replace('\r\n', ''))
このようなことが起きるので、複数の改行コード(例:\n, \t, \r, \r\n等)を削除したい場合はreplace()による置換ではなく、join()とsplitlines()による方法も検討しましょう。
''' splitlines()とjoin()を利用すると、そうした不安はありません。 '''
print(''.join(tanka.splitlines()))
ただし、削除したい改行コードが確実に1つのみである場合は、replaceメソッドの方が良いでしょう。その場合は、replace()の重ねがけも必要ないので、上の例のような予期せぬ出力結果になることはないと思います。
2. 正規表現の置換はreplace()ではなくre.sub()
ここからは、初学の段階では全く必須ではないので、ご興味のある方だけご覧ください。
Pythonにおける文字列の置換はreplaceメソッドが最も簡単で、よく使われています。ただし、replaceメソッドでは正規表現を扱うことはできません。正規表現はre.sub関数で扱います。
sub関数の基本構文
sub関数の基本構文は次の通りです。
import re #最初にreモジュールをインポート。
re.sub(正規表現パターン(=置換したい文字), 新しい文字, 対象の文字列 [,置換回数])
まず、sub関数は、reモジュールの関数なので、最初に”import re”でモジュールを読み込んでおく必要があります。モジュールについては、「Pythonのモジュールとは」をご覧ください。
reモジュールには、正規表現を使用したメソッドが揃っています。
置換したい文字列は、正規表現のパターンで指定します。例えば、アルファベットの全ての文字列を、別の新しい文字列に置換したければ、[a-z]と書きます。他には、最初は、^ は行の先頭を意味する。$ は行の終わりを意味するなどがあります。
これらは、正規表現について学習する時に再度触れていきましょう。
それでは、これの使い方の例を見ていきましょう。
2.1. 複数の文字列を一度に別の文字列に置換する
次の例をご覧ください。まずは、正規表現のパターンを指定しない場合です。
import re
text = "私たちのお店では、北海道の水や、四国のみずなど日本全国のミズを揃えています。"
new_text = re.sub(r'水|みず|ミズ', "water", text)
print(new_text)
この例では、置換したい文字に”水|みず|ミズ”と入力して、それらを”water”に置換しています。このようにsub関数では、置換したい文字列を複数一度に指定することができます。
replaceメソッドより便利な点の1つですね。ただし、replace()の重ねがけのように、置換したい文字を複数、入れ替える新しい文字を複数というような置換はできません。
2.2. 複数の文字列を1度に1つの別の文字列に置換
続いて次の例をご覧ください。
import re
text = "abc123def456efg"
new_text = re.sub(r'[a-z]', "0", text)
print(new_text)
小文字のアルファベットが全て、0 に置換されていますね。これは、置換したい文字列に[a-z]と正規表現を入力しているからです。この正規表現は、「小文字アルファベット全て」を意味します。
次の例もご覧ください。
import re
text = "abc123def456efg"
new_text = re.sub(r'[a-z]+', "0", text)
print(new_text) # 012304560
置換したい文字列に入力している正規表現の後ろに+を入力しました。出力結果を見てみると、アルファベットの連続した文字列が全て1つの0に置換されていますね。
これは、正規表現「+」が、直前の文字列の繰り返し全てを指定するものだからです。つまり、「+」を入れることによって、小文字アルファベットが連続した文字列が、全て1つの置換対象として見なされるのですね。
2.3. 改行を含む文章の置換
次からの例は、侍エンジニア塾さんの「【Python入門】reモジュールを使った正規表現の置換」に掲載されているものです。
それでは見ていきましょう。
次のような改行を含む3行に渡るコードです。改行を含む文字列は、変数に代入するときに、以下のように前後を3つずつのクオートで囲み、改行して記述すると作成することができます。
複数行に渡るコメントアウト(参照:「Pythonのコメントアウトのルール」)も、クオート3つで前後を挟むのですが、この場合は変数に代入しているのでコメントアウトとは見なされません。
import re
text = """
070-1234-5678 Tokyo
080-1234-5678 Chiba
090-1234-5678 Saitama
"""
new_text = re.sub("^[0-9]{3}-[0-9]{4}-[0-9]{4}","***-****-****",text)
print (new_text)
この例では、3行に渡るコードの、1行目の電話番号だけアスタリスク(*)に置換されています。
一つずつ見ていきましょう。
まず、正規表現パターン(置換したい文字列)には “^[0-9]{3}-[0-9]{4}-[0-9]{4}” と入力されていますね。まず「^」は、文字列の先頭を指定する正規表現です。
改行以降は、文字列の先頭として見なされないので、実行結果では、1行目だけがアスタリスクになります。
もし、最初の「^」を指定しないと、次のように、全ての番号が置換されます。
import re
text = """
070-1234-5678 Tokyo
080-1234-5678 Chiba
090-1234-5678 Saitama
"""
new_text = re.sub("[0-9]{3}-[0-9]{4}-[0-9]{4}","***-****-****",text)
print (new_text)
次に [0-9]{3}-[0-9]{4}-[0-9]{4} というように入力されていますね。
例えば [0-9]{3} で一つの正規表現です。最初の[0-9]で、0から9の全ての数字を表しており、{3}で3桁の数字を表しています。つまり、[0-9]{3} という正規表現は、0から9の数字のいずれかを含む3桁の数字という意味になります。
[0-9]{4}は、4桁の数字ですね。それぞれ、電話番号の上3桁、中4桁、下4桁を表します。
そのため、これを実行すると、指定した電話番号がアスタリスクに置換されるのですね。
2.4. ブロック単位での置換
次の例をご覧ください。
text="""
1234567 東京都千代田区
3334444 東京都港区
9876543 東京都台東区
"""
new_text = re.sub(r"([0-9]{3})([0-9]{4})", r"\1-\2", text)
print (new_text)
郵便番号を示す7桁の数字に、3桁 + 4桁の区切りでハイフンが挿入されました。
r”([0-9]{3})([0-9]{4})”, r”\1-\2″, text と入力しています。
まず、正規表現(置換したい文字列)を、([0-9]{3})([0-9]{4})として、上3桁と、下4桁を括弧で分けています。これは、その次の新しい文字列の “\1-\2” と対応しているからです。
「\1」は、検索文字列(置換したい文字列)の1番目という意味です。ここでは検索文字列の1番目は、([0-9]{3}) です。「\2」は、([0-9]{4}) に対応します。つまり、”\1-\2″ は、([0-9]{3}) と ([0-9]{4}) の間にハイフンを挿入するという意味になります。
このように正規表現を知って、sub関数を使いこなせるようになると、文字列の置換の幅が広がるのですね。
3. まとめ
Pythonの文字列の置換方法について見てきました。
まずはreplaceメソッドを使いこなせるようになることを目標にしましょう。そのあと、より詳細な分析など、プログラミング上の必要性が出てきたら、正規表現も学習して、sub関数を使いこなせるようになると良いでしょう。
最後に、ポイントをまとめておきます。
replaceメソッドの重要ポイントのまとめは次の通りです。
- replaceは新しい文字列を作るメソッドのため元の文字列に変化はない。
- 英語の大文字と小文字は区別して認識される。
- replaceは文字を単語ではなく1文字ずつの連なりとして認識している。
- 置換前と置換後の文字数は一緒でなくても構わない。
sub関数の重要ポイントのまとめは次の通りです。
- 正規表現とは、「様々な文字列を1つの文字列で表現する方法」。
- 正規表現パターンの文字列の前の r の入力を癖づける。
一つずつ、焦らずに学習していきましょう。
コメント