[解決!Python]文字列から部分文字列を削除する基本的なやり方とは(replace/translate/strip/removeprefix/removesuffixメソッド、re.sub関数)解決!Python

文字列が持つ各種メソッドやreモジュールのsub関数を使って、文字列内にある特定の文字列を削除する方法を紹介する。

» 2021年01月22日 05時00分 公開
[かわさきしんじDeep Insider編集部]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

「解決!Python」のインデックス

連載目次

# 定型の部分文字列を削除:replaceメソッド
s1 = 'https://www.atmarkit.co.jp/ait/articles/2101/19/news022.html'
s2 = s1.replace('https://', ''# 'https://'を削除(空文字列に置換)
print(s2)  # www.atmarkit.co.jp/ait/articles/2101/19/news022.html

# 特定の文字群を一括して削除:translateメソッド
s1 = 'name: [shinji+kawasaki], height: 172, weight: 80'
tbl = str.maketrans('+', ' ', ' []')
s2 = s1.translate(tbl)
print(s2)  # name:shinji kawasaki,height:172,weight:80
s3 = s2.split(',')
print(s3)  # ['name:shinji kawasaki', 'height:172', 'weight:80']
d = dict([item.split(':') for item in s3])
print(d)  # {'name': 'shinji kawasaki', 'height': '172', 'weight': '80'}

# 文字列の先頭/末尾にある空白文字を削除:strip/lstrip/rstripメソッド
s1 = '  ==** sample text **==  '
s2 = s1.strip()  # 文字列s1の先頭/末尾にある空白文字を削除
print(s2)  # ==** sample text **==

s2 = s1.strip(' ='# 引数に指定した文字を文字列s1の先頭/末尾から削除
print(s2)  # ** sample text **

s2 = s1.lstrip(' =*'# 引数に指定した文字を文字列s1の先頭から削除
s3 = s1.rstrip(' =*'# 引数に指定した文字を文字列s1の末尾から削除
print('lstrip:', s2)  # lstrip: sample text **==
print('rstrip:', s3)  # rstrip:   ==** sample text

# 特定のプレフィックス/サフィックスを削除:removeprefix/removesuffixメソッド
s1 = '_start_ sample text _end_'
s2 = s1.removeprefix('_start_'# 文字列が'_start_'で始まっていれば、それを削除
print(s2)  #  sample text _end_

s2 = s1.removesuffix('_end_'# 文字列が'_end_'で終わっていれば、それを削除
print(s2)  # _start_ sample text

# 正規表現を使う
import re
s1 = 'foo bar baz foo'
s2 = re.sub('foo', '', s1)  # 削除したい文字列/空文字列/対象の文字列
print(s2)  #  bar baz

s2 = re.sub(' *foo *', '', s1)  # 'foo'の前後に空白文字があればそれも一緒に削除
print(s2)  # bar baz


定型の部分文字列を削除する:replaceメソッド

 文字列のreplaceメソッドは、文字列中で指定したものを別の文字列に置き換えた新しい文字列を作成するが、置換後の文字列として空文字列を指定することで、指定した文字列を削除できる。一定のフォーマットを持つ文字列を順次処理して、特定部分を取り除く(残りの部分を抽出する)ようなときにはreplaceメソッドが便利だろう。

 以下に例を示す。

s1 = 'https://www.atmarkit.co.jp/ait/articles/2101/19/news022.html'
s2 = s1.replace('https://', ''# 'https://'を削除(空文字列に置換)
print(s2)  # www.atmarkit.co.jp/ait/articles/2101/19/news022.html

url_list = [
  'https://www.atmarkit.co.jp/ait/articles/2101/19/news022.html',
  'https://www.atmarkit.co.jp/ait/articles/2101/20/news036.html'
]

stripped_url_list = []
for url in url_list:
  tmp = url.replace('https://', '')
  stripped_url_list.append(tmp)

# stripped_url_list = [url.replace('https://', '') for url in url_list]


 最初の例では、文字列'https://www.atmarkit.co.jp/ait/articles/2101/19/news022.html'を対象に、置換前の文字列に'https://'として、置換後の文字列に空文字列を指定して、replaceメソッドを呼び出している。置換後の文字列が空文字列なので、置換前の文字列'https://'が削除され、'www.atmarkit.co.jp/ait/articles/2101/19/news022.html'が返送されている。ここでは示さないが、削除(置換)を実行する回数を第3引数に指定することも可能だ。

 2つ目の例は、1つ目の例をforループ(あるいはコメントにあるようにリスト内包表記)で処理する例だ。

 replaceメソッドでは一度に1つの文字列の置換しか行えない。1つの文字列に対して、置換したい文字列が複数含まれているようなときには、replaceメソッドを繰り返し実行する。

s1 = 'https://www.atmarkit.co.jp/ait/articles/2101/19/news022.html'
s2 = s1.replace('https://', '').replace('.html', ''# replaceメソッドを連鎖
print(s2)  # www.atmarkit.co.jp/ait/articles/2101/19/news022


特定の文字群を一括して削除する:translateメソッド

 今見たように、replaceメソッドを連鎖させることで置換を複数回行える。が、文字列に含まれる何種類かの文字(記号など)を置換したり削除したりしたいのであれば、replaceメソッドを連鎖させるよりもtranslateメソッドを使った方がスッキリとコードを書けるかもしれない。

 translateメソッドは文字列に含まれる何かの1文字を、別の文字列または文字に変換するものだ。どの文字をどんな文字列(文字)に変換するかはstr.maketransスタティックメソッドを使って作成する「変換テーブル」に記述して、それを使ってtranslateメソッドを呼び出す。これについては「[解決!Python]文字列を置換するには(replace/translate/expandtabsメソッド)」も参照のこと。

 あまりよい例ではないが(恣意(しい)的な例だが)、'name: [shinji+kawasaki], height: 172, weight: 80'という文字列があったとしよう。これを加工して、辞書に{'name': 'shinji kawasaki', 'height': 172, 'weight': 80}のように登録したいとする。そのためには次のような手順を踏むことになるだろう。

  1. 空白文字と大かっこ「[]」を削除する
  2. 加算記号「+」を空白文字に置換する
  3. カンマ「,」で区切って'キー:値'という文字列を要素とするリストを作成する
  4. できたリストの要素をコロン「:」で区切り、[キー,値]というリストを要素とするリストを作成して、それをdict関数に渡す

 これを実際のコードにしたのが以下だ。

s1 = 'name: [shinji+kawasaki], height: 172, weight: 80'
tbl = str.maketrans('+', ' ', ' []')
s2 = s1.translate(tbl)
print(s2)  # name:shinji kawasaki,height:172,weight:80
s3 = s2.split(',')
print(s3)  # ['name:shinji kawasaki', 'height:172', 'weight:80']
d = dict([item.split(':') for item in s3])
# d = {k: v for k, v in [item.split(':') for item in s3]}
print(d)  # {'name': 'shinji kawasaki', 'height': '172', 'weight': '80'}


 str.maketransスタティックメソッドでは、上記の1と2の処理をまとめて行っている。つまり、第1引数に'+'を、第2引数に' 'を指定することで加算記号を空白文字に変換して、第3引数には' []'を指定することで、元の文字列からそれらを一括で削除するような変換テーブルを作成している。この変換テーブルを使ってtranslateメソッドを呼び出すことで余計な空白を含まない文字列ができるので、次にカンマを区切りとして、その文字列をリストへ分割する。できたリストは['name:shinji kawasaki', 'height:172', 'weight:80']のようになっているので、今度はリスト内包表記を使ってその各要素をコロンで分割し、2要素のリスト(['name', 'shinji kawasaki']など)を要素とするリストを作成して、それをdict関数に渡すことで辞書を作成している。

 このように、文字列に含まれる記号類の変換や削除をまとめて行えるので、覚えておくとよいだろう。

文字列の先頭/末尾にある空白文字を削除:strip/lstrip/rstripメソッド

 文字列の先頭/末尾にある空白文字(や特定の文字)を削除するには、strip/lstrip/rstripメソッドが使える。機械的に入手した、あるいは不定形なフォーマットで入力された文字列では、ほしい文字列の前後に空白文字がくっついていることもある。そうした場合には、これら3つのメソッドで簡単に空白文字を取り除ける。

 引数を指定せずにこれらのメソッドを呼び出せば、stripメソッドでは文字列の先頭/末尾から、lstripメソッドでは文字列の先頭から、rstripメソッドでは文字列の末尾から空白文字が削除される。

 以下に例を示す。

s1 = '  ==** sample text **==  '

s2 = s1.strip()  # 文字列s1の先頭/末尾にある空白文字を削除
print(s2)  # ==**_sample_text_**==
print(s2.replace(' ', '_'))  # ==**_sample_text_**==(確認用)

s2 = s1.lstrip()  # 文字列s1の先頭にある空白文字を削除
print(s2)  # ==** sample text **== 
print(s2.replace(' ', '_'))  # ==**_sample_text_**==__(確認用)

s2 = s1.rstrip()  # 文字列s1の末尾にある空白文字を削除
print(s2)  #   ==** sample text **==
print(s2.replace(' ', '_'))  # __==**_sample_text_**==(確認用)


 ここでは文字列' ==** sample text **== 'を元の文字列とする。3つのメソッド呼び出しでは引数を指定していないので、stripメソッドは文字列の先頭/末尾にある空白文字を、lstripメソッドは文字列の先頭にある空白文字を、rstripメソッドは文字列の末尾にある空白文字を削除する。

 それぞれのメソッドの戻り値に対して、空白文字をアンダースコアに変換した結果も同時に表示するようにしているので、結果を確認してほしい。

 これらのメソッドは多くの場合、空白文字を取り除くために使われるが、引数を指定することで、それに含まれている文字を一括して(文字列の先頭/末尾から)取り除くのにも使える。

s1 = '  ==** sample text **==  '

s2 = s1.strip(' ='# 引数に指定した文字を文字列s1の先頭/末尾から削除
print(s2)  # ** sample text **

s2 = s1.lstrip(' =*'# 引数に指定した文字を文字列s1の先頭から削除
s3 = s1.rstrip(' =*'# 引数に指定した文字を文字列s1の末尾から削除
print('lstrip:', s2)  # lstrip: sample text **==
print('rstrip:', s3)  # rstrip:   ==** sample text


 ここでは、3つのメソッドに引数として文字列' ='を指定している。これにより、文字列の先頭/末尾に含まれている空白文字と等号「=」が削除されるようになる。

 3つのメソッドに引数を指定したときには、それは削除したい文字の集合として解釈されることには注意が必要だ。上の例では引数には文字列' ='を指定しているが、これは「空白文字+等号」という文字の並びを削除するのではなく、「文字列の先頭/末尾にある空白文字と等号は全て削除する」という意味だ。

 そのため、これらのメソッドが自分の想定とは異なる振る舞いをすることもある。以下はその例だ。

s1 = 'test.txt'
s2 = s1.rstrip('.txt'# 文字列s1から拡張子を削除するつもり
print(s2)  # tes


 文字列s1には'test.txt'という文字列(恐らくはファイル名)が代入され、s2にはその拡張子である'.txt'をrstripメソッドで削除したものを代入しようとしている。しかし、これを実行すると、「tes」と表示されてしまう。rstripメソッドに渡した文字列'.txt'はあくまでも削除したい文字の集合であり、rstripメソッドは文字列末尾にある文字「.」「t」「x」「t」を全て取り除いてしまう。よって、'.txt'の直前にある文字't'まで削除されてしまったということだ。

 こうした想定外の削除が発生しないようにするには、以下で紹介する2つのメソッドを使用する。

Copyright© Digital Advantage Corp. All Rights Reserved.

スポンサーからのお知らせPR

注目のテーマ

AI for エンジニアリング
「サプライチェーン攻撃」対策
1P情シスのための脆弱性管理/対策の現実解
OSSのサプライチェーン管理、取るべきアクションとは
Microsoft & Windows最前線2024
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。