文字列中の特定の部分文字列や特定の文字を、replace/translateメソッドを使って別の文字列や文字に変換する方法を紹介。タブ文字を空白文字に展開する方法も取り上げる。
# replaceメソッドによる文字列置換
s1 = 'this is a sample string'
s2 = s1.replace('this', 'that') # replaceメソッドは新しい文字列を返す
print(s1) # this is a sample string
print(s2) # that is a sample string
s2 = s1.replace(' ', '') # 第2引数を空文字列にすると置換前の文字列が削除される
print(s2) # thisisasamplestring
s1 = 'foo bar baz foo bar baz foo bar baz'
s2 = s1.replace('foo', 'FOO', 2) # 置換を行う回数を指定
print(s2) # FOO bar baz FOO bar baz foo bar baz
s2 = s1.replace('foo', 'FOO').replace('bar', 'BAR') # replaceメソッドを連鎖
print(s2) # FOO BAR baz FOO BAR baz FOO BAR baz
# maketransメソッドで変換テーブルを作成して、translateメソッドで置換
d = {' ': '_', 't': 'TT', 'a': None} # ' 'を'_'に、't'を'TT'に、'a'は削除
tbl = str.maketrans(d) # 辞書dを基に変換テーブルを作成
s1 = 'this is a sample string'
s2 = s1.translate(tbl)
print(s2) # TThis_is__smple_sTTring
tbl = str.maketrans(' a', '_A') # 半角空白文字をアンダースコアに、'a'を'A'に
s2 = s1.translate(tbl)
print(s2) # this_is_A_sAmple_string
tbl = str.maketrans('bcde', 'BCDE', 'a') # 'b'〜'e'を大文字に、'a'は削除
s2 = s1.translate(tbl)
print(s2) # this is smplE string
# タブ文字を半角空白文字に置換
s1 = '01\t4\t89'
s2 = s1.expandtabs(4) # 4タブでタブ文字を半角空白文字に展開
print(s2) # 01 4 89
Pythonで文字列に含まれる特定の部分文字列を別の文字列へ置換するには幾つかの方法がある。まずは最も代表的なreplaceメソッドを紹介する。
replaceメソッドを呼び出すときには、第1引数に置換前の文字列を、第2引数に置換後の文字列、第3引数に置換を行う回数を指定する。第3引数は省略可能だ。省略したときには置換前の文字列が置換後の文字列へと全て置換される。第2引数に空文字列''を指定すると、置換前の文字列が削除された文字列が得られる。文字列内に第1引数に指定した置換前の文字列が含まれていない場合は、元の文字列が戻り値となる。
このとき注意しなければいけないのは、replaceメソッドやこの後紹介するtranslateメソッド、expandtabsメソッドは全て新しい文字列を戻り値として返す点だ。元の文字列の内容が置き換えられるわけではない(文字列は変更不能なオブジェクト)。
以下に例を示す。
s1 = 'this is a sample string'
s2 = s1.replace('this', 'that') # replaceメソッドは新しい文字列を返す
print(s1) # this is a sample string
print(s2) # that is a sample string
この例では、置換前の文字列は'this is a sample string'で、replaceメソッドには置換前の部分文字列として'this'を、置換後の部分文字列として'that'を指定している。これにより、'this'が'that'に置換された新しい文字列が変数s2に代入される。そのため、変数s1には元の文字列が代入されたままとなっているのに注目しよう。
第2引数に空文字列''を指定すると、置換前の文字列が削除される。
s1 = 'this is a sample string'
s2 = s1.replace(' ', '') # 第2引数を空文字列にすると置換前の文字列が削除される
print(s2) # thisisasamplestring
次の例は置換回数を指定するものだ。
s1 = 'foo bar baz foo bar baz foo bar baz'
s2 = s1.replace('foo', 'FOO', 2) # 置換を行う回数を指定
print(s2) # FOO bar baz FOO bar baz foo bar baz
この例では、'foo bar baz'が3回繰り返されている文字列を対象に'foo'を'FOO'に置換している。ただし、replaceメソッドの第3引数には置換回数として「2」を指定しているので、置換は2回しか行われない。
ここまでに見たように、replaceメソッドは第1引数に指定した文字列を、第2引数に指定した文字列に置換する。文字列内に置換したい文字列が複数種類あるときには、replaceメソッドを繰り返し呼び出せばよい。
以下に例を示す。
s1 = 'foo bar baz foo bar baz foo bar baz'
s2 = s1.replace('foo', 'FOO').replace('bar', 'BAR') # replaceメソッドを連鎖
print(s2) # FOO BAR baz FOO BAR baz FOO BAR baz
この例では、文字列'foo'を'FOO'に、文字列'bar'を'BAR'に置換するために、replaceメソッドを連鎖して呼び出している。replaceメソッドの戻り値は文字列なので、このように連続的に呼び出せる。
replaceメソッドは特定の文字列を別の文字列へと置換するものだったが、特定の1文字を別の文字(文字列)へ置換するメソッドもある。それがtranslateメソッドだ。translateメソッドでは、置換対象の文字列内でどの文字をどの文字へ変換するのかを示す「変換テーブル」というオブジェクトを基に置換を実行する。変換テーブルは、文字列が持つmaketransスタティックメソッドを用いて作成する。
maketransスタティックメソッドは大きく分けて、2つの方法で変換テーブルを作成する。
変換テーブルを作成したら、置換対象の文字列でtranslateメソッドを呼び出して、それに作成した変換テーブルを渡すだけで、テーブルを基に置換処理を行った結果が新しい文字列として返される。
以下に例を示す。まずは最初の方法から見てみよう。
d = {' ': '_', 't': 'TT', 'a': None} # ' 'を'_'に、't'を'TT'に、'a'は削除
tbl = str.maketrans(d) # 辞書dを基に変換テーブルを作成
print(tbl) # {32: '_', 116: 'TT', 97: None}
s1 = 'this is a sample string'
s2 = s1.translate(tbl)
print(s2) # TThis_is__smple_sTTring
辞書には「{置換前の1文字: 置換後の文字(文字列), ……}」のようにして、どのような置換を行うかを指定していく。「置換前の1文字」には文字を1つだけしか指定できないことには注意。
ここでは、辞書dに「{' ': '_', 't': 'TT', 'a': None}」という3つの組を格納している。つまり、半角空白文字' 'を'_'に、文字't'を文字列'TT'に置換しようということだ。文字'a'をキーとする値はNoneとなっているが、これは文字'a'を削除することを意味している。
この辞書をstr.maketransスタティックメソッドに渡すと、変換テーブルが作成される。その内容は上に示した通り、「{32: '_', 116: 'TT', 97: None}」のようになっている。最初の組のキーとなっている「32」というのは半角空白文字のコードポイント(ord(' '))であり、他のキーについてもこれは同様である。
そして、置換対象の文字列でtranslateメソッドを呼び出して、作成した変換テーブルを渡してやれば、置換が行われる。
次に、2つ目の例を見てみよう。
s1 = 'this is a sample string'
tbl = str.maketrans(' a', '_A') # 半角空白文字をアンダースコアに、'a'を'A'に
print(tbl) # {32: 95, 97: 65}
s2 = s1.translate(tbl)
print(s2) # this_is_A_sAmple_string
tbl = str.maketrans('bcde', 'BCDE', 'a') # 'b'〜'e'を大文字に、'a'は削除
s2 = s1.translate(tbl)
print(s2) # this is smplE string
1つ目の例ではstr.maketransスタティックメソッドに文字列を2つ渡している。第1引数には置換前の1文字を集めた文字列を、第2引数には置換後の「1文字」を集めた文字列を渡す。このとき、2つの文字列の長さは等しい必要がある。そして、同じインデックスにある文字同士が置換前の文字から置換後の文字へと置き換えられる。先ほどの方法では、特定の1文字を任意の長さの文字列に置換できたが、こちらの方法では、ある1文字は違う1文字へと変換することしかできないことには注意しよう。
第1引数には' a'という文字列を渡していて、第2引数には'_A'を渡しているので、これは' 'を'_'に、'a'を'A'に置き換えたいということだ。maketransメソッドが返してきた変換テーブルを見ると、その内容は「{32: 95, 97: 65}」となっている。キーとなっている数値は先ほどと同様に置換前の文字のコードポイントであり、対応する値は置換後の文字のコードポイントである。
そして、translateメソッドを呼び出して、この変換テーブルを渡すと、今述べたように' 'が'_'に、'a'が'A'に置換されているのが分かる。
2つ目の例では、str.maketransスタティックメソッドに置換前の文字の集合として'bcde'を、置換後の文字の集合として'BCDE'を指定している(つまり、大文字化)。そして、第3引数には文字'a'を指定している。第3引数に指定した文字は削除の対象となる。そのため、これにより作成された変換テーブルを使用して、文字列'this is a sample string'を置換すると、文字列内の'e'が'E'に置換され、文字'a'が削除される。
最後にタブ文字を半角空白文字に置換するexpandtabsメソッドも紹介しておこう。これは文字列に含まれているタブ文字('\t')を指定したタブ幅で半角空白文字に変換するものだ。以下に例を示す。
s1 = '01\t4\t89'
s2 = s1.expandtabs(4) # 4タブでタブ文字を半角空白文字に展開
print(s2) # 01 4 89
print(s2.replace(' ', '_')) # 01__4___89(比較用)
s1 = '01\t89A'
s2 = s1.expandtabs(8) # 8タブでタブ文字を半角空白文字に展開
print(s2) # 01 89A
print(s2.replace(' ', '_')) # 01______89A(比較用)
なお、正規表現を使用してより高度な形で文字列の置換を行う方法もあるが、これについては別稿で解説する予定だ。
Copyright© Digital Advantage Corp. All Rights Reserved.