Pythonで正規表現を使う方法です。[br num=”1″]今回は数字について書きました。
○○以上○○以下とか、郵便番号や電話番号のパターンチェックなどを例に紹介しています。
Pythonの正規表現には、reモジュールを使う
正規表現は英語でregexとか、regular expressionと書きます。[br num=”1″]そして、reはその略ですね。
文字列が部分一致しているかどうかは、reモジュールのmatch関数を使います。
一部分だけじゃなくて全部一致しているかどうか確認するなら、fullmatch関数です。
re.match(パターン, 文字列)
re.fullmatch(パターン, 文字列)
パターンには、パターン用の書き方があります。[br num=”1″]raw文字列というヤツです。
- 次のように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]のように書きます。
[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/