Python中級プログラミング(3)
2025/02/22
正規表現オブジェクトのメソッド
  • 前回から期間かなり空きました(*1)が、正規表現オブジェクトのメソッドとフラグ(動作制御)について説明します。

  • Pythonの正規表現オブジェクトは、前回使用したsearch()を含め下記のメソッドを持ちます(*2)
  • メソッド説明
    search()文字列内全体を検索し、最初のマッチ部をマッチオブジェクトで戻す
    findall()文字列内全体を検索し、マッチ部全てをリストで戻す
    finditer()文字列内全体を検索し、マッチ部全てをマッチオブジェクトのイテレータで戻す
    sub()文字列内全体のマッチ部を置換し、文字列データを戻す
    split()文字列全体をマッチ部で分割し、リストを戻す

  • マッチオブジェクトと正規表現オブジェクトのフラグ(動作制御)も扱います。
    • マッチオブジェクトについては、search()メソッドと一緒に説明します。
    • メソッドの後は、正規表現オブジェクトのフラグ(動作制御)を扱います。


メソッド: search()
  • 前回及び前々回のレポートでsearch()を使っているので、何となくおわかりと思いますが、search()はマッチした先頭の文字列をマッチオブジェクトで戻します
  • import re
    
    # マッチ/キャプチャ結果をマッチオブジェクトで受け取る
    str_base = "2 4a 8 16b 32 64c"
    o_match = re.search(r"\d+[a-z]", str_base)
    
    # マッチオブジェクトからの結果取り出し
    if o_match:
        print("str_ele=", o_match.group(0)) # キャプチャ文字列全体
        print("str_ele=", o_match.start(0)) # キャプチャ文字列の開始位置
        print("str_ele=", o_match.end(0))   # キャプチャ文字列の終了位置(+1)
    
    >test.py
    str_ele= 4a # 最初にキャプチャした 4a だけが取り込まれる
    str_ele= 2  # 文字列 4a の開始位置
    str_ele= 4  # 文字列 4a の終了位置(+1)
    
    #2 4a 8 16b 32 64c
    #0123456789
    #  | |
    #  | end(=4)
    #  start(=2)
    
  • 結果表示部でマッチオブジェクトのメソッドを使っています。
    • group(番号): キャプチャした文字列: 0/省略は全体: 1~はグループ番号
    • start(番号): キャプチャ文字列開始位置: 0/省略は全体: 1~はグループ番号
    • end(番号): キャプチャ文字列終了位置: 0/省略は全体: 1~はグループ番号

  • 正規表現でグループ化を使用すると上記「1~はグループ」の出番です。これは使用例を見た方が早いでしょう。
  • import re
    
    # マッチ/キャプチャ結果をマッチオブジェクトで受け取る
    str_base = "記録の日付 2025/02/23"
    o_match = re.search(r"(\d+)/(\d+)/(\d+)", str_base)
    
    if o_match:
        print("group0:", o_match.group(0), ",start:", o_match.start(0), ",end:",o_match.end(0)) # 全体
        print("group1:", o_match.group(1), ",start:", o_match.start(1), ",end:",o_match.end(1)) # 年
        print("group2:", o_match.group(2), ",start:", o_match.start(2), ",end:",o_match.end(2)) # 月
        print("group3:", o_match.group(3), ",start:", o_match.start(3), ",end:",o_match.end(3)) # 日
    
    >test.py
    group0: 2025/02/23 ,start: 6 ,end: 16
    group1: 2025 ,start: 6 ,end: 10
    group2: 02 ,start: 11 ,end: 13
    group3: 23 ,start: 14 ,end: 16

メソッド: findall()
  • findall()は文字列内でマッチする全ての文字列をリストにして戻します。search()はマッチした先頭の文字列をマッチオブジェクトで戻しますが、findall()は全てをリストで戻す点が異なります。
  • import re
    
    # マッチ/キャプチャ結果をリストで受け取る
    str_base = "2 4a 8 16b 32 64c"
    list_ret = re.findall(r"\d+[a-z]", str_base)
    
    print("str_base=", str_base)
    
    if list_ret:
        for str_ele in list_ret:
            print("str_ele=", str_ele)
    
    >test.py
    str_base= 2 4a 8 16b 32 64c
    str_ele= 4a
    str_ele= 16b
    str_ele= 64c

メソッド: finditer()
  • finditer()メソッドはマッチする全ての文字列を個々のマッチオブジェクトに格納し、そのイテレータを戻します
  • import re
    
    # マッチ/キャプチャ結果をマッチオブジェクトのイテレータで受け取る
    str_base = "2 4a 8 16b 32 64c"
    iter_match_ret = re.finditer(r"\d+[a-z]", str_base)
    
    print("str_base=", str_base)
    
    if iter_ret:
        for o_match in iter_match_ret:
            print("o_match.group=", o_match.group())
    
    >test.py
    str_base= 2 4a 8 16b 32 64c
    o_match.group= 4a
    o_match.group= 16b
    o_match.group= 64c

メソッド: sub()
  • sub()メソッドはマッチする文字列を指定文字列に置換します。グループ化を利用した場合、置換文字列にも後方参照を利用することができます。
    • デフォルトはマッチする文字列を全て置換します。
    • subメソッドのcount引数に数値を指定 (例:re.sub(r"[a-z]", "#", 2)) することで置換回数を設定できます。
    import re
    
    str_base = "2 4a 8 16b 32 64c"
    
    # 通常置換
    str_ret0 = re.sub(r"[a-z]", "#", str_base)
    # 後方参照を利用した置換
    str_ret1 = re.sub(r"(\d+)", r"@\1", str_base)
    
    print("str_base=", str_base)
    print("str_ret0=", str_ret0)
    print("str_ret1=", str_ret1)
    
    >test.py
    str_base= 2 4a 8 16b 32 64c
    str_ret0= 2 4# 8 16# 32 64#
    str_ret1= @2 @4a @8 @16b @32 @64c
    

メソッド: split()
  • split()は文字列オブジェクト自身にもある、デリミタ文字列指定による分割/リスト化のメソッドですが、正規表現オブジェクトのメソッドは、デリミタのパターン指定に正規表現を使用することができます
  • import re
    
    # ハチャメチャなデリミタを正規表現を使って分割する
    str_base = "2, 4a: 8 16b; 32 64c"
    print("str_base=", str_base)
    
    list_ret = re.split(r"[,:;]*\s+", str_base)
    
    if list_ret:
        for str_ele in list_ret:
            print("str_ele=", str_ele)
    
    >test.py
    str_base= 2, 4a: 8 16b; 32 64c
    str_ele= 2
    str_ele= 4a
    str_ele= 8
    str_ele= 16b
    str_ele= 32
    str_ele= 64c


正規表現オブジェクトのフラグ
  • 正規表現オブジェクトの代表的な動作制御フラグには下記があります。
  • フラグ短縮表記説明
    re.ASCIIre.Aマッチ条件の半角限定制御
    re.IGNORECASEre.Iマッチ条件の大文字/小文字無視制御
    re.MULTILINEre.M^(先頭)及び$(末尾)の複数行マッチ許可制御

  • IGNORECASEとMULTILINEは、正規表現の標準的な機能のそれぞれ「iフラグ」と「mフラグ」相当なので上記表内コメント以上の説明は省略します。

  • 残りの re.ASCII ですが、これはPython独自になります。

  • 通常Pythonの正規表現文字クラス(\d,\s,\w)マッチ条件は、半角/全角文字ともに有効です。 つまり普通に
      list_ret = re.findall(r"\w+", "半a 半b 全a 全b")
    と書けば、半角データ/全角データ全ての要素にマッチします。
  • import re
    
    list_ret = re.findall(r"\w+", "半a 半b 全a 全b")
    
    if list_ret:
        for str_ele in list_ret:
            print("str_ele=", str_ele)
    
    >test.py
    str_ele= 半a
    str_ele= 半b
    str_ele= 全a
    str_ele= 全b
    
  • しかし、下記のようにASCIIフラグを指定した場合、半角(ASCII)データのみが有効となります。
  • import re
    
    list_ret = re.findall(r"\w+", "半a 半b 全a 全b", flags=re.A)
    
    if list_ret:
        for str_ele in list_ret:
            print("str_ele=", str_ele)
    
    >test.py
    str_ele= a
    str_ele= b
    

次回
  • 次回は関数を扱いますが、その関数でデータを受け渡しする際に理解が必要となるデータの参照(リファレンス)について話をしたいと思います。
Notes
  • 近いうちにちょっとしたテキストを作る必要が出てしまったのです。
  • 他にも、match(), fullmatch(), subn()等ありますが、使う機会は少ないでしょう。
2025/02/22: 初版
2025/02/23: search()メソッドとマッチオブジェクト説明追加
Copyright(C) 2025 Altmo
本HPについて