Pythonの正規表現モジュールが提供する関数を使って、文字列から数字だけを抽出する方法を紹介する。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
import re
s = '2021年03月12日 15時30分'
m = re.findall(r'\d+', s) # 文字列から数字にマッチするものをリストとして取得
print(m) # ['2021', '03', '12', '15', '30']
r = ''.join(m)
print(r) # 202103121530
r = re.sub(r'\D', '', s) # 元の文字列から数字以外を削除=数字を抽出
print(r) # 202103121530
# re.search関数は最初にマッチするものだけを返送する
m = re.search(r'\d+', s)
r = m.group()
print(r) # 2021
# re.search関数で全ての数字を抽出する
m = re.search(r'(\d+)\D+(\d+)\D+(\d+)\D+ +(\d+)\D+(\d+)\D+', s)
r = m.groups()
print(r) # ('2021', '03', '12', '15', '30')
r = m.group(2)
print(r) # 03
文字列を抽出する基本的な方法については「[解決!Python]インデックスやスライスを使って文字列から一部を抽出するには」「[解決!Python]re.findall関数と正規表現を使って文字列から部分文字列を抽出するには」「[解決!Python]re.search/re.match関数と正規表現を使って文字列から部分文字列を抽出するには」を参照のこと。
文字列から数字のみを抽出するには、Pythonが標準で提供する正規表現モジュール「re」のfindall関数を使うのが簡単だ。数字(UnicodeのGeneral_Categoryプロパティの値が「Nd」である文字)を表す正規表現は「\d」であり、1文字以上の繰り返しを意味する「+」と組み合わせて「\d+」とすることで「1文字以上の数字」を表せる。これと対象の文字列をre.findall関数に渡せば、その文字列で「1文字以上の数字」にマッチする全ての部分を要素とするリストが取得できる。
以下に例を示す。
import re
s = '2021年03月12日 15時30分'
m = re.findall(r'\d+', s) # 文字列から数字にマッチするものをリストとして取得
print(m) # ['2021', '03', '12', '15', '30']
この例では、数字で構成される部分が5つあるが、それらがリストの要素となっていることに注目されたい。マッチした部分を個別に取り出せるので、後から必要な部分を利用するのも簡単だし、ひとまとめにすることも簡単だ。
from datetime import datetime
d = datetime(*[int(item) for item in m]) # datetimeクラスのインスタンス生成
print(d) # 2021-03-12 15:30:00
r = '-'.join(m) # 取得した文字列を結合
print(r) # 2021-03-12-15-30
1つ目の例では、取得した文字列要素を整数に変換したリストを作成し、それを展開したものをdatetimeクラスのコンストラクタに渡すことで、このクラスのインスタンスを生成している。2つ目の例では単純に文字列を要素とするリストを文字列のjoinメソッドに渡すことで、新たな文字列を作成している。
re.findall関数のように数字にマッチする部分を個別の要素として取り出す必要はなく、全てをひとまとめにした文字列を1個だけ取り出せればよいという場合もあるかもしれない。そのときには、re.sub関数を使って、「数字以外を削除した」=「数字だけを抽出した」文字列を作成するという方法もある。
以下に例を示す。
r = re.sub(r'\D', '', s) # 元の文字列から数字以外を削除=数字を抽出
print(r) # 202103121530
数字以外を表す正規表現は「\D」であり、これを空文字列「''」に置換するように、re.sub関数に伝えれば、元の文字列から数字以外の文字が削除された(数字だけが抽出された)文字列が得られる。文字列に数字が含まれているのが1カ所だけの場合など、こちらの方法で十分ということもあるだろう。
Copyright© Digital Advantage Corp. All Rights Reserved.