任意の文字(列)を置換する関数3つについて、それぞれの特徴と使い方について解説します。
- str.replace()
- str.translate()
- re.sub()
確認した環境
- OS: Ubuntu 20.04LTS@WSL2
- Python: ver3.9.7
文字(列)を置換する関数の特徴
それぞれの関数の特徴を表にまとめました。
特徴 | |
---|---|
str.replace() |
|
str.translate() |
|
re.sub() |
|
以降、それぞれの関数の使い方の詳細について記載します。
str.replace()を使った文字列の置換
replace() は文字列のメソッドで、引数に指定した部分文字列を全て置き換えます。
使い方は下記のとおりです。
str.replace(old, new[, count])
- 第一引数old: 置き換え前の文字(列)
- 第二引数new: 置き換え後の文字(列)
- オプション引数count: 先頭(左側)から何回置き換えるか
返り値は、置換後の文字列のコピーです。元のデータは書き換えられません。
具体例を下記に示します。
>>> s = 'abc-def-abc-def-bac'
# 文字列"abc"を"xyz"に置き換える
>>> s.replace('abc', 'xyz')
'xyz-def-xyz-def-bac'
# 元の文字列は変更されません
>>> s
'abc-def-abc-def-bac'
引数countは、先頭(一番左端)から置換する回数を設定します。
下記に具体的にいろいろ試してみました。
>>> s = 'o_o_o_o_o'
# count = 2
>>> s.replace('o', 'x', 2)
'x_x_o_o_o'
# count = 4
>>> s.replace('o', 'x', 4)
'x_x_x_x_o'
# count = 10 (置換可能の個数より多い場合は全部置換されます)
>>> s.replace('o', 'x', 10)
'x_x_x_x_x'
# count = 0
>>> s.replace('o', 'x', 0)
'o_o_o_o_o'
# count = -1 (マイナスの数値を指定すると全部置換されました)
>>> s.replace('o', 'x', -1)
'x_x_x_x_x'
文字の入れ替えについては、ひと手間必要です。
単純に2回繰り返してもうまく行きません。
>>> s = "o_x_o_x_o"
# 一回目のreplaceで置換した後、二回目のreplaceで全部置換されます
>>> s.replace('o', 'x').replace('x', 'o')
'o_o_o_o_o'
この場合、例えば下記のようにダミーの置換を途中にはさむと可能です。
>>> s = "o_x_o_x_o"
# ダミーで'o' -> '*'の置換を挿入
>>> _s = s.replace('o', '*') # *_x_*_x_*
>>> __s = _s.replace('x', 'o') # *_o_*_o_*
>>> res = __s.replace('*', 'x')
>>> res
'x_o_x_o_x'
# 一文で書くと下記
>>> s.replace('o', '*').replace('x', 'o').replace('*', 'x')
'x_o_x_o_x'
str.translate()を使った文字の置換
str.translate() は、置き換え表を用いて文字(文字列)を置き換えます。
使い方は以下です。
str.translate(table)
引数tableは先に述べた文字の「置き換え表」です。
また、この関数は置き換え後のコピーを返すので、元のデータは変わりません。
置き換え表はstr.maketrans() を使って作成できます。
具体例を下記に示します。
- 文字の置換(例:’o’ -> ‘x’)
>>> s = "o_o_o_o_o"
# 置き換え表の作成
>>> table = str.maketrans('o', 'x')
# 置換処理
>>> s.translate(table)
'x_x_x_x_x'
文字列’abc’ -> ‘xyz’の置換ではないことに注意。
>>> s = "abc-oxo-cba-abc"
# 置き換え表の作成
# 置換する文字をつなげて記述します
>>> table = str.maketrans('abc', 'xyz')
# 置換処理
# 'cba'も置換されていることに注意
>>> s.translate(table)
'xyz-oxo-zyx-xyz'
削除したい文字はmaketrans()の第三引数に指定します。
>>> s = "abc-oxo-cba-abc"
# 置き換え表の作成
>>> table = str.maketrans('abc', 'xyz', 'o')
# 置換処理
>>> s.translate(table)
'xyz-x-zyx-xyz'
尚、置き換え表maketrans()の第一引数(置換元の文字)と第三引数(削除する文字)が同じ文字の場合は、第三引数が優先されます。
# 'o' → 'x'の置換と'o'削除を同時に設定した場合
>>> str.maketrans('o', 'x', 'o')
{111: None}
# これは下記と同じ処理になるためと考えられます。
# dict型の右側の要素で上書きされる為
>>> str.maketrans({'o':'x', 'o':None})
{111: None}
また、置き換え表には複数の文字の置換パターンを設定できるため、文字の交換も簡単に記述できます。
下記に具体例を示します。
>>> s = "o_x_o_x_o"
# 置き換え表の作成
>>> table = str.maketrans('ox', 'xo')
# 置換処理
>>> s.translate(table)
'x_o_x_o_x'
<参考記事> 詳細はこちらの記事をご参照ください。
正規表現(re.sub)を使った文字列の置換
正規表現re.sub() を使うと、文字列のパターンを指定して置き換え出来ます。
re.sub(pattern, repl, string, count=0, flags=0)
引数はそれぞれ以下の通り。
- 第一引数pattern: 置き換え前の文字列の正規表現パターン
- 第二引数repl: 置き換え後の文字列、または関数
- 第三引数string: 検索する文字列
- オプション引数count: 先頭(左)から何回置き換えるか
返り値は、置換された文字列のコピーです。元の文字列は変わりません。
以下に例を示します。
- 文字列の置換
# 'a' → 'x'の置換
>>> s = 'abcd'
>>> re.sub(r'a', 'x', s)
'xbcd'
# 'abc'→'xyz'の置換
>>> s = "abc-oxo-cba-abc"
>>> re.sub(r'abc', 'xyz', s)
'xyz-oxo-cba-xyz'
置換回数は引数countで設定できます。
この値は非負整数で、count=0または省略の場合は全部置換されます。
# 'o'→'x' 3回置換の場合(count=3)
>>> re.sub(r'o', 'x', s, 3)
'x_x_x_o_o'
# count=0または省略の場合は全部置換
>>> re.sub(r'o', 'x', s, 0)
'x_x_x_x_x'
>>> re.sub(r'o', 'x', s)
'x_x_x_x_x'
例1)3つ並んだ数値を’***’に置き換える
>>> s = '123-abc-456-def-789-ghi'
>>> re.sub(r'\d{3}', '***', s)
'***-abc-***-def-***-ghi'
# count=2とすると、先頭から2個の文字列を置換
>>> re.sub(r'\d{3}', '***', s, 2)
'***-abc-***-def-789-ghi'
例2)3つ並んだ小文字のアルファベット(aからz)を’***’に置き換える
>>> s = '123-abc-456-def-789-ghi'
>>> re.sub(r'[a-z]{3}', '***', s)
'123-***-456-***-789-***'
# count = 2とすると、先頭から2個の文字列を置換
>>> re.sub(r'[a-z]{3}', '***', s, 2)
'123-***-456-***-789-ghi'
尚、第二引数replは関数(引数はマッチオブジェクト)を設定することができます。これを使うと、translate()と同じような動作が書けます。
例えば、以下は複数文字の置換(例:’a’ → ‘x’、’b’ → ‘y’、’c’ → ‘z’)の例です。(もっと効率の良い書き方があるかもしれません)
>>> def func(matchobj):
... d = {'a':'x', 'b':'y', 'c':'z'}
... return d[matchobj.group(0)]
...
>>> re.sub(r'[abc]', func, 'abc-xyz-cba')
'xyz-xyz-zyx'
同様に文字の交換も以下のように書けます。
>>> def func(matchobj):
... d = {'o':'x', 'x':'o'}
... return d[matchobj.group(0)]
...
>>> re.sub(r'[ox]', func, 'o_x_o_x_o')
'x_o_x_o_x'
<参考> 正規表現パターンの詳細はこちらの記事にて解説しています。ご参照ください。
まとめ
Pythonで文字(列)を置換する際に用いる3つの関数の使い方についてまとめました。それぞれの特徴に応じて効率的になるよう使い分けていきたいですね。
- str.replace()
- str.translate()
- re.sub()