【Python】カンマのある数値・X桁の数値だけを取得する正規表現

本記事では文字列から数値/数値だけを取得する正規表現をご紹介します.

  • カンマのある数値(価格など)から数値をカンマ付きで取得
  • カンマを除いた数値だけを取得
  • X桁の数値だけを取得

事前準備

今回は正規表現を使用するのでPythonの標準ライブラリのreimportします.


import re

正規表現を使用して数値部分を抽出

まずはコンマのある数値部分を抽出する方法です.
「1,000,000円」のような文字列からコンマ+数値部分を抽出します.


s1 = '1,000,000円'
s1_r1 = re.search(r'[\d,]+', s1).group()
print(s1_r1)
1,000,000

上記は正規表現を使って,を含めて数値を取得しています.

カンマを除く場合

前項で取得した文字から,を除きたい場合は以下のようにします.


s1_r2 = s1_r1.replace(',', '')
print(s1_r2)
1000000

Pythonの組み込みメソッドのreplaceを使用してコンマを置換しています.
,を取り除くと組み込みのint()などを使用して数値に変換することができます.1

なお,文字列の形式が統一されている場合は以下のような方法でも可能です.


s1 = '1,000,000円'

s1_r3 = s1[:-1].replace(',', '')
print(s1_r3)
1000000

上記の方法は変換対象の文字列の最後が必ず「円」で終わるという前提で成り立ちます.
桁数の増減や,がない場合は許容されますが「円」がないと適切に数値が取れません.
以下の例を見てみましょう.


# 数値を取得したい文字列のリスト
sl = ['100円', '10,000円', '5,000', '2000円']


# 正規表現なし
sl_r1 = [s[:-1].replace(',', '') for s in sl]
# 正規表現あり
sl_r2 = [re.search(r'[\d,]+', s).group().replace(',', '') for s in sl]

print(sl_r1)
print(sl_r2)
['100', '10000', '500', '2000']
['100', '10000', '5000', '2000']

リスト内の「5,000」には「円」が付いていないので正規表現を使っていない方の結果では「500」になっています.一方で正規表現の場合はこうした表記揺れがあっても正しく数値を取得できています.

数値部分が複数ある場合の取得方法

「500円〜1,000円」のように文字列中に取得したい数値が複数ある場合の取得方法です.
reライブラリのfindallメソッドを使用します.


s2 = '500円〜1,000円'
s2_r = re.findall(r'[\d,]+', s2)
print(s2_r)
['500', '1,000']

findallメソッドでは指定した正規表現に合致する文字列をリストで取得します.
今回は2つの数値が含まれているため,2つの数値が取得できています.

なお,を除きたい場合は以下のようにします.


s2_r2 = [s.replace(',', '') for s in s2_r]
print(s2_r2)
['500', '1000']

特定の桁数の数値を取得する方法

商品コードなど,特定の桁数を取得する際には以下のようにします.


s3 = '商品コード: 12345, 商品コード: 6789'
print(re.findall(r'(?<!\d)\d{4}(?!\d)', s3))
['6789']

4桁の数値に限定するためには上記のような正規表現になります.2

任意の桁数を取得する場合

\d{4}4が取得する数値の桁数になっているので,この数値を変更すれば任意の桁数を取得できます.

もし,文字列に出てくる数値が固定されている場合は以下でも可能です.


s4 = '商品コード: 1234, 商品コード: 5678'
print(re.findall(r'\d{4}', s4))
['1234', '5678']

\d{4}は1〜9の数値が4個続いた場合にマッチするので,4桁の数値を取得できます.

ただし,この正規表現の場合は4桁以上の数値にもマッチするので注意が必要です.
以下で見てみましょう.


s3 = '商品コード: 12345, 商品コード: 6789'
print(re.findall(r'\d{4}', s3))
['1234', '6789']

最初の商品コードは12345と5桁ですが,数値が4個続いている最初の4桁が正規表現にマッチするので,最初の4桁を取得してしまいます.

参考

「文字列に含まれる数値は4桁以下」かつ「取得したい数値が4桁」である場合も\d{4}が使えます.
(3桁以下の数値はマッチしないからです)


s5 = 'コード1, コード22, コード345, コード6789, コード1111'
print(re.findall(r'\d{4}', s5))
['6789', '1111']

ひとこと

色々な数値を取得する内容を見てきましたが,もっとよい方法をご存知の方がいればぜひお知らせください!


  1. ,があるとint()で数値に変換することができません. 

  2. 否定的後読み/先読みを使って4桁の数値だけが取れるようにしていますが,他によい方法あればご連絡ください.