【完全版】Pythonで文字列を抽出する方法まとめ

Pythonでstr型の文字列から特定の文字列を抽出する方法をよく使うパターンごとにまとめました。

【完全版】Pythonで文字列を抽出する方法まとめ

Pythonでテキストシーケンス型のstrから文字列を抽出する方法について、よく使うパターンをもとに解説します。

正規表現で文字列を抽出・置換する方法や文字列を分割してリストで取得する方法については以下の記事で解説しているので参考にしてください。

文字列の位置を指定して抽出する(インデックスとスライス)

Pythonの文字列操作の基本として、インデックスとスライスによる位置指定があります。

インデックス指定による文字列抽出

str型の文字列に対して、[ ]でインデックスを指定することでその位置の文字を抽出することができます。インデックスは0から始まるので注意してください。例えば、文字列'Hello, World!'の、1文字目と6文字目を抽出するには、次のようにします。

s = 'Hello, World!'

print(s[0])
# 'H'

print(s[5])
# ','

スライスによる文字列抽出

文字列のスライスでは、文字列を指定した範囲で切り出すことができます。

文字列のスライスの書式はstring[start:end:step]のようになります。

  • start: 切り出しを開始するインデックス。省略すると0。
  • end: 切り出しを終了するインデックス。省略すると文字列の長さ。
  • step: インデックスをどのように取るかを指定する。省略すると1。

例えば、文字列'Hello, World!'から、2文字目から5文字目までを切り出すには、次のようにします。

# 2文字目から5文字目までを切り出す
s = 'Hello, World!'
substring = s[1:5]
print(substring)
# 'ello'

文字列のスライスは、書式を省略することができます。例えば、文字列の先頭から5文字を切り出すには、次のようにします。

# 文字列の先頭から5文字を切り出す
s = 'Hello, World!'
substring = s[:5]
print(substring)
# 'Hello'

また、文字列のスライスでは、負のインデックスを使って、文字列の末尾から数えた位置を指定することもできます。例えば、文字列の末尾から2文字を切り出すには、次のようにします。

# 文字列の末尾から2文字を切り出す
s = 'Hello, World!'
substring = s[-2:]
print(substring)
# 'd!'

文字列のスライスでは、ステップを指定することもできます。例えば、文字列を1文字おきに切り出すには、次のようにします。

# 文字列を1文字おきに切り出す
s = 'Hello, World!'
substring = s[::2]
print(substring)
# 'Hlo ol!'

特定の文字で囲まれた文字列を抽出する

任意の文字で囲まれた文字列を抽出するには、スライスとインデックスを利用します。

# [ ]で囲まれた文字列を抽出する
s = '[example] this is an example string'
start = s.index('[') + 1  # 最初の'['の位置を特定し、次の文字の位置を取得
end = s.index(']')  # 最初の']'の位置を特定
captured = s[start:end]
print(captured) 
# 'example'

また、正規表現を使った方法も利用することができます。Pythonでは正規表現モジュールのreを使用します。

次の例では、文字列'[example] this is an example string'から'[example]'のように'['']'で囲まれた文字列を抽出しています。

# [ ]で囲まれた文字列を抽出する
import re

s = '[example] this is an example string'
pattern = r'\[(.+?)\]'  # []で囲まれた文字列を抽出する正規表現
match = re.search(pattern, s)
if match:
    captured = match.group(1)
    print(captured)  # 'example'

文字列を指定した区切り文字で分割して抽出する

Pythonで文字列を区切り文字で分割して抽出するには、標準ライブラリのstr.split()メソッドを使用することができます。

このメソッドは、文字列を指定した区切り文字で分割して、その結果をリストとして返します。区切り文字を省略すると、空白文字(スペース、タブ、改行)で分割されます。

以下は、文字列をコンマで分割して抽出する例です。

# 文字列をコンマで分割して抽出
s = "Apple,Banana,Orange"
fruits = s.split(',')
print(fruits)
# ['Apple', 'Banana', 'Orange']


# 分割された文字列の二番目の要素を取り出す
second_fruit = fruits[1]
print(second_fruit)
# Banana

また、split()メソッドは、分割された文字列を最大何回分割するかを指定することもできます。2番目の引数に分割する回数を指定します。指定した回数より多くの区切り文字がある場合、指定した回数以降の文字列は、最後にまとめて1つの文字列として返されます。

以下は、文字列をコンマで分割して、最大3個の要素に分割する例です。

# 文字列をコンマで最大3つの要素に分割して抽出
s = "Apple,Banana,Orange,Grape,Peach"

# split()メソッドでコンマで分割し、最大2回分割する
fruits = s.split(',', 2)

print(fruits)
# ['Apple', 'Banana', 'Orange,Grape,Peach']

文字列を特定の文字列以降や特定の文字列以前だけ抽出する

文字列のスライスを使用することで、特定の文字列以降や特定の文字列以前だけを抽出することができます。

例えば、以下のようにすると、文字列の"d"以降の文字列や、"d"より前の文字列を抽出することができます。インデックスの位置により、その文字自体が含まれるかどうかが変わるので、注意してください。

# 文字列'd'以降の文字を抽出する
s = "abcdefghijklmnopqrstuvwxyz"
d_index = s.index("d")
print(s[d_index:])
# "defghijklmnopqrstuvwxyz"

# 文字列'd'より前の文字を抽出する
print(s[:d_index])
# "abc"

文字列から数値だけを抽出する

Pythonで文字列から数値だけを抽出するには、正規表現を使用する方法が便利です。

正規表現モジュールreの、re.findall()関数を使用して、文字列から数値を抽出します。re.findall()関数は、正規表現にマッチする文字列をすべて抽出してリストで返す関数です。

正規表現としては、以下のようにすると、数値を抽出することができます。

import re

s = "abc123def456"

# r'\d'は数字を意味し、'+'は直前のパターンの1回以上の繰り返しの意味
numbers = re.findall(r'\d+', s)
print(numbers)
# ['123', '456']

# 正規表現から'+'を抜くと、連続した数値ではなく1つずつ抽出される
numbers = re.findall(r'\d', s)
print(numbers)
# ['1', '2', '3', '4', '5', '6']

文字列から小数点のついた数値のみを抽出する

文字列から小数点のついた数値のみを抽出する場合も、正規表現を使用します。

# 文字列から小数点のついた数値のみを抽出する
import re

s = "とある確率:50.4%、別の確率:99.9%"
numbers = re.findall(r'\d+\.\d+', s)
print(numbers)
# ['50.4', '99.9']

上記の例では、文字列sから、数字が1つ以上連続し、その後に小数点が1つあり、さらに数字が1つ以上連続する部分を抽出しています。正規表現では、小数点は\.と表すことができます。

抽出した文字列を、小数型の変数に代入するには、以下のようにします。

import re

s = "とある確率:50.4%、別の確率:99.9%"
numbers = re.findall(r'\d+\.\d+', s)
numbers = [float(decimal) for decimal in numbers] # float型に変換
print(numbers)
# [50.4, 99.9]

print(type(numbers[0]))
# <class 'float'>

また、特定のパターンの文字とまとめて抽出したい場合もあります。

例えば、以下のようにすると、文字列sから、数字が1つ以上連続し、その後に小数点が1つあり、さらに数字が1つ以上連続し、その後に'%'がついた部分を抽出することができます。

import re

s = "とある確率:50.4%、別の確率:99.9%"
numbers = re.findall(r'\d+\.\d+%', s)
print(numbers)
# ['50.4%', '99.9%']

文字列を含むリストから特定の条件のものを抽出する

filter()関数を使用すると、リストから特定の条件を満たすものを抽出することができます。

filter()関数は、指定した関数を適用した結果がTrueである要素だけを取り出す関数です。

以下の例では、文字列の大きさが4以上の要素を抽出しています。判定用の関数で、str型を引数にbool型を返すものであれば別の条件で絞ることも可能です。

# 4文字以上の文字列かどうかを判定する関数
def is_long_string(s):
    return len(s) > 3

s_list = ['abc', 'defg', 'hij', 'klmno']
filtered = filter(is_long_string, s_list)
print(list(filtered))
# ['defg', 'klmno']

また、リスト内包表記を利用するとシンプルに記述できて便利です。リスト内包表記では、if以降の条件にマッチしたものだけをリストの要素として格納してくれます。処理速度も通常のfor文を書くより早くて効率的なため、可能な限りこの表記を使いましょう。

# 4文字以上の文字列かどうかを判定する関数
s_list = ['abc', 'defg', 'hij', 'klmno']
filtered = [s for s in s_list if len(s) > 3]
print(list(filtered))
# ['defg', 'klmno']

# 条件にマッチしないものを抽出するパターン
filtered = [s for s in s_list if not len(s) > 3]
print(list(filtered))
# ['abc', 'hij']