本ページはプロモーションが含まれています

【Python】任意の文字列を置換する(str.replace, str.translate, re.sub)

Python文字列正規表現組込み型組込み関数

任意の文字(列)を置換する関数3つについて、それぞれの特徴と使い方について解説します。

  • str.replace()
  • str.translate()
  • re.sub()

スポンサーリンク

確認した環境

  • OS: Ubuntu 20.04LTS@WSL2
  • Python: ver3.9.7

文字(列)を置換する関数の特徴

それぞれの関数の特徴を表にまとめました。

特徴
str.replace()
  • 文字列の置換が可能
  • 引数で指定した一つの置換パターンのみ実行。その為、文字の交換には工夫が必要
  • 置換候補が複数ある場合は、回数を指定可能
str.translate()
  • 文字の置換が可能
  • 「置き換え表」に指定した複数の置換パターンを実行可能。よって、文字の交換も一回のtranslate()で処理可能
  • 置換回数は指定できず、該当する文字はすべて置換
re.sub()
  • 正規表現パターンにマッチした文字列の置換が可能
  • 第二引数replを関数で設定し工夫することで、translate()相当の処理は可能?
  • 置換候補が複数ある場合は、置換する回数を指定可能

以降、それぞれの関数の使い方の詳細について記載します。

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'
  • 複数文字の置換(例:’a’ → ‘x’、’b’ → ‘y’、’c’ → ‘z’)
  • 文字列’abc’ -> ‘xyz’の置換ではないことに注意。

    >>> s = "abc-oxo-cba-abc"
    
    # 置き換え表の作成
    # 置換する文字をつなげて記述します
    >>> table = str.maketrans('abc', 'xyz')
    
    # 置換処理
    # 'cba'も置換されていることに注意
    >>> s.translate(table)
    'xyz-oxo-zyx-xyz'
  • 複数文字の置換+削除(例:’a’ → ‘x’、’b’ → ‘y’、’c’ → ‘z’ + ’o’削除
  • 削除したい文字は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'

<参考記事> 詳細はこちらの記事をご参照ください。

【Python】str.translate()を用いた文字の置換
str.translate()は文字を置換する際に用いる関数です。文字の置き換え表を引数として渡す必要がありますが、本記事ではstr.maketrans()を用いた文字の置き換え表の作成方法と合わせて具体例を用いてわかりやすくまとめます。

正規表現(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】正規表現 reモジュールの使いかたの基本
Pythonで正規表現マッチング操作を行うには、reモジュールを使います。本記事では、reモジュールを使った正規表現マッチング操作の基本、および文字列の置き換えや分割等の文字列操作について具体例を挙げながらまとめます。

まとめ

Pythonで文字(列)を置換する際に用いる3つの関数の使い方についてまとめました。それぞれの特徴に応じて効率的になるよう使い分けていきたいですね。

  • str.replace()
  • str.translate()
  • re.sub()

参考書籍

書籍でもう少し詳しく学びたい場合はこちらもどうぞ。筆者もかなり参考にさせてもらっています!

シェアする
ひびきをフォローする
Hbk project