見出し画像

『退屈なことはPythonにやらせよう』7章 正規表現を使ったパターンマッチのらくがき帳📝

こんにちは。aliceです。
最近はびっくりしたことは、気づいたら保冷剤をレンジで温めていたことです。
暑いって怖いですね。

クーラーってすばらしい!!


今回は『退屈なことはPythonにやらせよう』第7章 正規表現を使ったパターンマッチのらくがき帳です。

正規表現はわからなずぎて(暗号か顔文字にしか見えなくて)読む気がしなかったのですが、ゆっくりで良いから解読してみよう!と思えるようになったのが良かったです✨

前回のらくがき帳📝


では、以下らくがきです。



7章 英語版🔤


GitHub💖


まえがき?

ほぉぉー、と思った!

「正規表現」をしていることは、問題を解くのに3,000ステップもかかっていたものが、3ステップで済むくらいの違いがある。専門馬鹿は自分なら数回キーを入力すれば済む問題が、普通の人にとっては面倒で、間違いやすく、遅々として進まぬ何日もかかる問題であることに思い至らない。



7.1 正規表現を用いないテキストパターン


まずは正規表現を使わないパターン。
郵便番号バージョンで書いてみた🖊

def is_post_code(text):
    if len(text) != 8:
        return False
    for i in range(0, 3):
        if not text[i].isdecimal():
            return False
    if text[3] != '-':
        return False
    for i in range(4, 8):
        if not text[i].isdecimal():
            return False
    return True


print('123-4567 は郵便番号?')
print(is_post_code('123-4567'))  # True
print('1234567 は郵便番号?')
print(is_post_code('1234567'))  # False


7.2 正規表現を用いてテキストパターンを検索する


正規表現を使うパターン。
確かにステップが短くて済む!!

import re

post_code_regex = re.compile(r'\d\d\d-\d\d\d\d')  # Regex objectを作成
mo = post_code_regex.search('My post code is 123-4567.')  # Regex objectのsearch()メソッドを呼び出す
print('Post code found: ' + mo.group())



7.2.3 正規表現マッチのまとめ


さすがに何回も「import re」と書いたのでそれは覚えた!

きれいなうみをみたい🐋


import re

# 正規表現パターンを定義
pattern = r'\d+'  # 1つ以上の数字にマッチするパターン

# 検索対象の文字列を定義
text = 'Hello, 123 World!'

# re.search()関数を使用して一致する部分を検索し、Matchオブジェクトを取得
match = re.search(pattern, text)

if match:
    # Matchオブジェクトが存在する場合、マッチした文字列を取得して表示
    matched_string = match.group()
    print("マッチした文字列:", matched_string)  # 123
else:
    # MatchオブジェクトがNoneの場合、一致する部分が見つからなかったことを表示
    print("一致する部分が見つかりませんでした。")


  • search()メソッドは最初に見つかった文字列のMatchオブジェクトを返す

  • findall()目そ度は見つかったすべての文字列を返す


7.3 正規表現によるパターンマッチの続き


たくさんあっておなかいっぱいになった。
とりあえずアプリに入れたので1週間くらい眺めます👀


まとめ

いろいろリンクがあったので貼ってみる。


公式ドキュメント


チュートリアルWebサイト


なんか好き。
たっくさんあるんですね。



7.18 演習プロジェクト

今回は「自分でやる」ではなくて「ChatGPTに書いてもらう」をやってみました。
一瞬でできるの、ほんとすごい。
作ってもらった正規表現を解読している感じです。

7.18.1 日付の検出

DD/MM/YYYYの形式の日付を検出する正規表現を書きましょう📝

import re


def is_valid_date(date_str):
    # 正規表現パターン:DD/MM/YYYY(うるう年を考慮)
    date_pattern = r'^(0?[1-9]|[1-2][0-9]|3[0-1])/(0?[1-9]|1[0-2])/((19|20)\d{2})$'

    # 正規表現で日付のフォーマットをチェック
    if not re.match(date_pattern, date_str):
        return False

    # 日、月、年の部分を取得
    day, month, year = map(int, date_str.split('/'))

    # 月が31日以内かチェック
    if month in [1, 3, 5, 7, 8, 10, 12] and day > 31:
        return False

    # 月が30日以内かチェック
    if month in [4, 6, 9, 11] and day > 30:
        return False

    # うるう年の2月かチェック
    if month == 2:
        if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
            # うるう年の場合
            if day > 29:
                return False
        else:
            # うるう年でない場合
            if day > 28:
                return False

    # すべてのチェックを通過した場合は、妥当な日付とみなす
    return True


# テスト
date_str = '29/02/2024'
if is_valid_date(date_str):
    print(f'{date_str}は有効な日付です。')
else:
    print(f'{date_str}は無効な日付です。')


正規表現についての解説


7.18.2 強いパスワード

引数として渡されたパスワードが強いかどうか、正規表現を用いて確認する関数を書きましょう📝
強いパスワードとは8文字以上、大文字と小文字を含み、1つ以上の数字を含みます。

import re


def is_strong_password(password):
    # 正規表現パターン:8文字以上、大文字と小文字を含み、1つ以上の数字を含む
    password_pattern = r'^(?=.*[A-Z])(?=.*[a-z])(?=.*\d).{8,}$'

    # 正規表現でパスワードの妥当性をチェック
    if re.match(password_pattern, password):
        return True
    else:
        return False


# テスト
password1 = "Secure123"
password2 = "weakpass"
password3 = "1pass12"
password4 = "VeryStrongPass12"

print(is_strong_password(password1))  # True
print(is_strong_password(password2))  # False
print(is_strong_password(password3))  # False
print(is_strong_password(password4))  # True


正規表現についての解説


7.18.3 正規表現を用いたstrip()メソッド

文字列を引数に取り、文字列メソッドのstrip()と同等の動きをする関数を作りましょう📝
デフォルトでは文字列の冒頭と末尾から空白文字を除去します。
追加の文字列引数があればそれを文字列の冒頭と末尾から削除します。

import re


def custom_strip(text, chars=None):
    # charsがNoneの場合は、デフォルトで空白文字を除去する正規表現を使用
    if chars is None:
        pattern = r'^\s+|\s+$'
    else:
        # charsに指定された文字列を正規表現の一部として使用する
        pattern = f'^[{re.escape(chars)}]+|[{re.escape(chars)}]+$'

    # 正規表現で文字列を置換して空白を除去
    return re.sub(pattern, '', text)


# テスト
text = "  Hello, World!  "
chars_to_remove = " !"
print(custom_strip(text))  # "Hello, World!"
print(custom_strip(text, chars_to_remove))  # "Hello, World"


正規表現についての解説

1年前だったら「正規表現を覚えよう」と思ったかもしれないけど、これだけ書いてもらえるので、今は「なんとなくわかればいっか」という気持ちになりました。

なんか不思議な気持ちです。

退屈なことはPythonとChatGPTにやっていただこうですね🙏


つづき


この記事が気に入ったらサポートをしてみませんか?