Python compileとVERBOSEできれいに記述

Python学習【365日チャレンジ!】287日目のマスターU(@Udemy11)です。

楽天のブラックフライデーセール真っ只中なので、必要なものだけでなく、前からほしいと思っていたものを購入して散財してしまいました。

一つの店舗で1,000円以上の買い物をするたびに、この期間に支払った金額に対して還元されるポイントが1倍ずつプラスされるので、買えば買うほどお得な感じがしてしまうんですよね。

調子よく次の商品を購入しようと思ったところ、知らない間に付与ポイントの上限(10,000ポイント)に達してしまったようで、付与予定ポイントが大幅に少なくなっていました。

気をつけないといけないのは、このポイントが期間限定で、12月31日までに付与されて、1月31日までの有効期限ということです。

値引きじゃなくて、ポイント付与なので、結局表示されている金額を使わないといけないんですよね。

100,000円のものが10%引きの90,000円で買えるのではなく、100,000円で、10,000円分の期間限定ポイントが付いて110,000円分の商品が買えるということです。

ついついセールにつられて不要なものまで買わないように気をつける必要がありますが、めっちゃオトクなことは間違いありませんので、ぜひこの機会に楽天市場で必要なアイテムを購入しましょう!

↓↓↓↓↓

それでは今日も、Python学習を始めましょう。

昨日の復習

昨日は、match()group()を使って、規則のある長い文字列から必要な情報を取り出す方法を学習しました。

AWSのCloudFormationで使用するStackIdから正規表現を使い、情報を抽出しましたが、長い文字列から正規表現を活用することで必要な情報を取り出して活用することができました。

詳細については昨日の記事をごらんください。

今日は、re.compilere.VERBOSEを使って、前回のコードを、よりシンプルでわかりやすくする記述方法を学習します。

compile

昨日学習したコードにもう一つ検索する文字列を加えて、forループで2つの文字列から値を抽出してみます。

import re

s1 = ('arn:aws:cloudformation:us-east-2:123098769012:stack/'
      'mystack-mynestedstack-safeahxhum7w/f449b250-b969-11e0-a185-5081d0136786')

s2 = ('arn:aws:cloudformation:us-east-1:123453234012:stack/'
      'mystack-mynestedstack-sggfbsrgsm7w/f449b250-b969-11e0-a185-5081d0133552')

for s in [s1, s2]:
    m = re.match(
        (r'arn:aws:cloudformation:(?P<region>[\w-]+):(?P<account_id>[\d]+)'
          ':stack/(?P<stack_id>[\w-]+)/[\w-]+'), s)
    print(m.group('region'))
    print(m.group('account_id'))
    print(m.group('stack_id'))

forループを使って、最初に値を入れた変数をリストで回してマッチを確認して、それぞれのregionaccount_idstack_idを出力しています。

出力結果

us-east-2
123098769012
mystack-mynestedstack-safeahxhum7w
us-east-1
123453234012
mystack-mynestedstack-sggfbsrgsm7w

データベースに保存されているデータをチェックする場合などに使えそうですが、同じ正規表現を別のところにも書く必要が出てきた時に、また長いコードを書くことになります。

そんな時に、最初に正規表現を指定しておいてから活用することができるのがre.compile()です。

import re

RE_STACK = re.compile(
    (r'arn:aws:cloudformation:(?P[\w-]+):(?P[\d]+)'
     ':stack/(?P[\w-]+)/[\w-]+'))

s1 = ('arn:aws:cloudformation:us-east-2:123098769012:stack/'
      'mystack-mynestedstack-safeahxhum7w/f449b250-b969-11e0-a185-5081d0136786')

s2 = ('arn:aws:cloudformation:us-east-1:123453234012:stack/'
      'mystack-mynestedstack-sggfbsrgsm7w/f449b250-b969-11e0-a185-5081d0133552')

for s in [s1, s2]:
    m = RE_STACK.match(s)
    print(m.group('region'))
    print(m.group('account_id'))
    print(m.group('stack_id'))

出力結果

us-east-2
123098769012
mystack-mynestedstack-safeahxhum7w
us-east-1
123453234012
mystack-mynestedstack-sggfbsrgsm7w

3行目から5行目のre.compile()で、正規表現を使った条件をグローバル変数のRE_STACKとして定義しておいて、14行目でRE_STACKを活用しています

グローバル変数にすることで、他の関数やクラスでも活用することができるので、無駄に長いコードを書く必要がなくなります。

VERBOSE

REVOSEを使うことで、compile()で記述した正規表現をコメントを付けて見やすく記述することができます。

RE_STACK = re.compile(r"""
    arn:aws:cloudformation:
    (?P[\w-]+):      #region
    (?P[\d]+):   #account_id
    stack/
    (?P[\w-]+)     #stack_id
    /[\w-]+""", re.VERBOSE)

コメントアウトでも使う"""(トリプルクォーテーション)で囲って第2引数にre.VERBOSEを指定することで、改行やスペースなどが入ってもコード的に無視してくれるので、正規表現のコメントなども記述してわかりやすくすることができます。

まとめ

長いコードを何度も使う場合はモジュール化して読み込みますが、同じように、正規表現の記述も変数に入れて何度でも活用することができました。

同じ正規表現の記述を何度も使う場合、何箇所も同じ記述をしてしまうと、変更する必要が出てくると、すべての記述を変更する必要があるので、変数にして定義しておけば、変数の中身を1度変更するだけですみます。

プログラムをパーツ化するのと一緒ですね。

シングルソースマルチユースの考え方同様に、よりシンプルかつ便利な使い方をマスターしましょう。

それでは、明日もGood Python!