プログラミングを勉強するサイトです。今まで使ってこなかった言語を新しく勉強し始めたのをきっかけに、プロブロを始めました。

【Python】正規表現で数字の範囲、桁数を指定する方法

【Python】正規表現で数字の範囲、桁数を指定する方法

 

Pythonで正規表現を使う方法です。[br num=”1″]今回は数字について書きました。

○○以上○○以下とか、郵便番号や電話番号のパターンチェックなどを例に紹介しています。

Pythonの正規表現には、reモジュールを使う

正規表現は英語でregexとか、regular expressionと書きます。[br num=”1″]そして、reはその略ですね。

文字列が部分一致しているかどうかは、reモジュールのmatch関数を使います。

一部分だけじゃなくて全部一致しているかどうか確認するなら、fullmatch関数です。

match関数、fullmatch関数の使い方

re.match(パターン, 文字列)

re.fullmatch(パターン, 文字列)

パターンには、パターン用の書き方があります。[br num=”1″]raw文字列というヤツです。

Pythonでのパターンの書き方
  • 次のようにraw文字列を使う
  • r’ここに正規表現の文字列を書く’

以降は、いろんな数字のパターンを紹介します。

○○桁の数字を指定する(半角、全角)

1桁の数字や2桁以上の数字を指定してみます。

1桁の数字

まずは1桁の数字から。

変数regexにパターンを格納し、match関数で判定した結果をbool関数でTrueなのかFalseなのか判定してみました。[br num=”1″]判定結果をprint関数で表示です。

import re

#1桁の数字
regex = r'([0-9])'
regex2 = r'(\d)'

#一致するかどうか見てみる
print(bool(re.match(regex, '7')))     #半角7
print(bool(re.match(regex, '7')))    #全角7
print(bool(re.match(regex2, '5')))    #半角5
print(bool(re.match(regex2, '5')))   #全角5

2通りの書き方を使ってみました。[br num=”1″]さっそく実行してみます。

半角の数字なら、どちらも同じようにTrueとなりました。[br num=”1″]しかし全角になると、判定結果が違うようです。[br num=”1″]全角と半角を区別しつつ、全角の数字について判定するなら、[0-9]のように書きます。

1桁の数字の正規表現

[0-9] :1桁の数字、全角半角の区別あり

[0-9]:1桁の数字、全角半角の区別あり

\d  :1桁の数字、半角全角の区別なし

任意の桁の数字

3桁や5桁の数字で試してみます。

import re

#3桁の数字
regex = r'([0-9]{3})'

#5桁の数字
regex2 = r'(\d{5})'

#一致するかどうか見てみる
print(bool(re.match(regex, '789')))        #半角789
print(bool(re.match(regex, '789')))      #全角789
print(bool(re.match(regex2, '56789')))      #半角56789
print(bool(re.match(regex2, '56789')))   #全角56789

{n}はn回繰り返すという意味です。[br num=”1″]{3}で1桁の数字を3回繰り返すわけです。

実行してみると・・・。

結果は1桁の場合と同じようになりました。

18以上65以下の場合

1桁の数字なら、3以上7以下だったら[3-7]のように書けます。[br num=”1″]では2桁以上の場合どうなるか。

まずは18以上65以下を例に書いてみます。

import re

#3桁の数字
regex = r'(1[8-9]|[2-5][0-9]|6[0-5])'

#一致するかどうか見てみる
print('17:'+str(bool(re.match(regex, '17'))))
print('18:'+str(bool(re.match(regex, '18'))))
print('41:'+str(bool(re.match(regex, '41'))))
print('65:'+str(bool(re.match(regex, '65'))))
print('66:'+str(bool(re.match(regex, '66'))))

3つに分けて書くことができます。

10の位が1のとき、18と19のどちらかです。[br num=”1″]なので、1[8-9]と表します。

20~59は[2-5][0-9]。[br num=”1″]ここは表現しやすいところです。

60以上は、6[0-5]と表します。

この3つのどれかに当てはまれば18以上65以下なので、~または~の「|」で繋げています。

では18、65など、中央値、境界値を見てみましょう。

中央値は当然ながら、境界値もしっかり判定できています。

桁数の範囲を指定する

今度は桁数の範囲を指定してみます。

1桁のところでも{n}の書き方を使いました。[br num=”1″]範囲指定はこれを使っていきます。

○桁から○桁の数字

桁数の範囲指定

{最小値, 最大値}

3桁から7桁なら、カンマ区切りで{3,7}と書きます。

import re

#3~7桁の数字
regex = r'([0-9]{3,7})'

#一致するかどうか見てみる
print(bool(re.match(regex, '01')))            #2桁
print(bool(re.match(regex, '012')))           #3桁
print(bool(re.match(regex, '1414213')))       #7桁
print(bool(re.match(regex, '14142135')))      #8桁
print(bool(re.fullmatch(regex, '1414213')))   #8桁
print(bool(re.fullmatch(regex, '14142135')))  #8桁

実行してみると・・・。

match関数の場合、3桁以上なら8桁の数字でもマッチしてしまいました。[br num=”1″]8桁の中に3~7桁の部分があるからです。

fullmatch関数の場合、7桁ならTrue、8桁でFalseとなりました。[br num=”1″]完全一致かどうか確認できています。

○○桁以下の数字

○○以下の範囲指定

{, 最大値}

「○○以上」のところを消して、「○○以下」だけ書きます。[br num=”1″]7桁以下なら、{,7}。

import re

#7桁以下の数字
regex = r'([0-9]{,7})'

#一致するかどうか見てみる
print(bool(re.match(regex, '01')))            #2桁
print(bool(re.match(regex, '012')))           #3桁
print(bool(re.match(regex, '1414213')))       #7桁
print(bool(re.match(regex, '14142135')))      #8桁
print(bool(re.fullmatch(regex, '1414213')))   #7桁
print(bool(re.fullmatch(regex, '14142135')))  #8桁

match関数、fullmatch関数それぞれ実行してみます。

7桁以下の場合、どちらもTrueになりました。

8桁でも、match関数なら7桁以下の部分が含まれるのでTrueとなりますが、fullmatch関数は8桁だとFalseになっています。

○○桁以上の数字

○○以上の範囲指定

{最小値, }

「○○以下」のところを消して、「○○以上」だけ書きます。[br num=”1″]3桁以上なら、{3, }。

import re

#3桁以上の数字
regex = r'([0-9]{3,})'

#一致するかどうか見てみる
print(bool(re.match(regex, '01')))            #2桁
print(bool(re.match(regex, '012')))           #3桁
print(bool(re.match(regex, '1414213')))       #7桁

3桁以上のパターンで、match関数を使ってみました。

2桁の場合False、3桁以上でTrueとなりました。

組み合わせて使ってみる

郵便番号や電話番号を例に、パターンが一致しているか判定してみます。

郵便番号の形式かどうか確認する

日本の郵便番号は、3桁の数字と4桁の数字をハイフンで繋いだ文字列です。

桁数が足りなかったり、ハイフンなし、正しい郵便番号の形式、桁数オーバーの4つをmatch関数で判定してみました。[br num=”1″]また、fullmatch関数で、一致している場合と桁数が多い場合を見てみました。

import re

#郵便番号
regex_post = r'([0-9]{3}-[0-9]{4})'

#match関数で確認
print(bool(re.match(regex_post, '11-4567')))       #間違った郵便番号
print(bool(re.match(regex_post, '1234567')))       #間違った郵便番号
print(bool(re.match(regex_post, '123-4567')))      #正規の郵便番号
print(bool(re.match(regex_post, '123-45678')))     #間違った郵便番号
#fullmatch関数で確認
print(bool(re.fullmatch(regex_post, '123-4567')))  #正規の郵便番号
print(bool(re.fullmatch(regex_post, '123-45678'))) #間違った郵便番号

実行します。

match関数だと桁数が多い場合にもTrueとなりました。

fullmatch関数なら、完全一致のみTrueとなりました。

携帯電話の形式かどうか確認する

郵便番号の例でだいたい分かってしまったと思いますが、携帯電話でもやってみます。

携帯電話は、先頭3桁が070、080、090の3通り。[br num=”1″]ハイフン有り無しは、-?でどちらもOKとなります。

携帯番号をmatch関数で確認

ではmatch関数から見てみましょう。

import re

#携帯電話番号
regex_post = r'(0[7-9]0-?[0-9]{4}-?[0-9]{4})'

#一致するかどうか見てみる
print(bool(re.match(regex_post, '03-1234-5678')))  #固定電話番号
print(bool(re.match(regex_post, '0120-000-000')))  #フリーダイヤル
print(bool(re.match(regex_post, '817012345678')))  #国際携帯電話番号
print('-----------')
print(bool(re.match(regex_post, '07012345678')))   #携帯電話番号ハイフンなし
print(bool(re.match(regex_post, '0801234567')))    #1桁足りない
print(bool(re.match(regex_post, '090123456789')))  #1桁多い
print('-----------')
print(bool(re.match(regex_post, '070-1234-5678')))  #携帯電話番号ハイフンあり
print(bool(re.match(regex_post, '080-1234-56789'))) #1桁多い
print(bool(re.match(regex_post, '090-1234-567')))   #1桁足りない

9通りの例を書いてみました。

070などで始まっていない場合は全部Falseの判定です。[br num=”1″]11桁の場合はTrueになりますが、12桁でもFalseにはなりません。[br num=”1″]-?[0-9]{4}のところで、5桁続いても4桁は部分一致しているためです。

やはりmatch関数ではムリがありますね。

fullmatch関数で確認してみる

match関数で書いていたところを、全部fullmatch関数に換えてみました。

import re

#携帯電話番号
regex_post = r'(0[7-9]0-?[0-9]{4}-?[0-9]{4})'

#一致するかどうか見てみる
print(bool(re.fullmatch(regex_post, '03-1234-5678')))  #固定電話番号
print(bool(re.fullmatch(regex_post, '0120-000-000')))  #フリーダイヤル
print(bool(re.fullmatch(regex_post, '817012345678')))  #国際携帯電話番号
print('-----------')
print(bool(re.fullmatch(regex_post, '07012345678')))   #携帯電話番号ハイフンなし
print(bool(re.fullmatch(regex_post, '0801234567')))    #1桁足りない
print(bool(re.fullmatch(regex_post, '090123456789')))  #1桁多い
print('-----------')
print(bool(re.fullmatch(regex_post, '070-1234-5678')))  #携帯電話番号ハイフンあり
print(bool(re.fullmatch(regex_post, '080-1234-56789'))) #1桁多い
print(bool(re.fullmatch(regex_post, '090-1234-567')))   #1桁足りない

実行してみます。

11桁の携帯番号のところだけ、Trueとなりマッチしていることが分かりました。

まとめ:正規表現で数字の範囲、桁数を指定する方法

まとめるとこんな感じです。

まとめ
  • 正規表現は、reモジュールを使う
  • 部分一致の確認はmatch関数
  • 完全一致ならfullmatch関数
  • パターンはRawで、r’パターン’のように指定する
  • 数字の範囲は、[最小値-最大値]
  • 桁数の範囲は、{最小桁数, 最大桁数}
  • 半端な数字は、~またはの「|」で各パターンを書く

今回は数字のみでやってきました。

英字も混在すると、英字用のパターンも必要になってきますので、また別の記事で書いていきます。

この記事をシェアする

記事一覧へ戻る

コメント Comments

コメント一覧

コメントはありません。

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トラックバックURL

https://pro-blo.com/python/regex-of-numbers/trackback/

関連記事 Relation Entry