Pythonで正規表現

python

正規表現の基本

  • 文字クラス:
    • [abc] : a, b, c のいずれかにマッチ
    • [^abc] : a, b, c 以外の文字にマッチ
    • [a-z] : a から z の範囲内の文字にマッチ
  • 特殊文字:
    • \d : 数字(0-9)にマッチ
    • \D : 数字以外にマッチ
    • \w : 英数字またはアンダースコアにマッチ([a-zA-Z_0-9]
    • \W : 英数字またはアンダースコア以外にマッチ
    • \s : 空白文字(スペース、タブなど)にマッチ
    • \S : 空白文字以外にマッチ
  • 量指定子:
    • * : 0回以上の繰り返し
    • + : 1回以上の繰り返し
    • ? : 0回または1回
    • {n} : 正確に n 回の繰り返し
    • {n,} : n 回以上の繰り返し
    • {n,m} : n 回以上、m 回以下の繰り返し

初心者歓迎!手と目で覚える正規表現入門・その1「さまざまな形式の電話番号を検索しよう」

https://qiita.com/jnchito/items/893c887fbf19e17d3ff9

Pythonでの利用

文字列の完全一致判定

import re

# ユーザーから郵便番号を入力
code = input('郵便番号を入力>>')

# 郵便番号のパターンを定義
pattern = r'\d{3}-?\d{4}'

# パターンに完全一致するか確認
m = re.fullmatch(pattern, code)
if m:
    print('ok')  # マッチした場合
else:
    print('ng')  # マッチしなかった場合

ポイント解説

● import re : pythonで正規表現を使うにはreモジュールをインポートする
●r’文字列’ :
Pythonでは改行を意味する\nのように\はエスケープシーケンスとして扱われる。
なので数字を表す\dを表すには\\dとして表す必要がある。
文字列を表すときに先頭にr(またはR)を付与するとrow文字列として扱われ、文字列内の文字はすべてそのままの形で扱われるので\を2重に表記する必要がなくなる。正規表現パターンを表記する際には便利だ。
●re.fullmatch(パターン,文字列): は完全一致するかを判定する。一致した場合にはmatchオブジェクトを返し、そうでなかった場合はNoneを返す。先頭から最後までをチェックするため、^や$をパターンで明示的に表す必要はない

部分一致判定

文字列に含まれるかどうかを判定するにはre.search()を使う

import re

s = 'りんご:100円,ばなな:50円'

pattern = r'\d+'

m = re.search(pattern,s)
if m:
    # matchした部分を取得
    print(m.group()) # 100
else:
    print('ng')

ポイント

re.searchは一つでもマッチした部分を見つけたらそれ以降の調査は行わない。
なのでばななの50を取得はできない。

一致をすべて取得

re.findallを使うと一致する部分を要素とするリストを取得できる

import re

s = 'りんご:100円,ばなな:50円'

pattern = r'\d+'

prices = re.findall(pattern,s)
if prices:
    print(prices) #[100,50]
else:
    print(ng)

置換

re.sub(パターン,置換後,対象文字列)
を使うことで置換した文字列を作成することができる

import re

s = 'りんご:100円,ばなな::50円'
s = re.sub(r'::?','->',s)
print(s) # りんご->100円,ばなな->50円 

キャプチャを使っての置換

subではキャプチャを使っての置換もできる

import re

s = 'りんご:100円,ばなな:50円'
s = re.sub(r'(\d+)円',r'¥\1',s)
print(s) # りんご:¥100,ばなな:¥50 

subでは第二引数に関数を渡せる

第2引数に関数を指定することもできる。引数としてmatchオブジェクトが渡されるのでそこからgroup(1)でキャプチャされた文字を取得している。

import re

s = 'りんご:100円,ばなな:50円'

# 価格を2倍にする関数
def calc(match):
    # キャプチャされた価格を整数に変換して2倍にする
    price = int(match.group(1)) * 2
    # f文字列を使って価格を返す
    return f'{price}円'

# 正規表現で数字+円をマッチさせてcalc関数で置換
s = re.sub(r'(\d+)円', calc, s)

# 結果の表示
print(s)  # 出力: りんご:200円,ばなな:100円

英単語、正規表現検索

以下のくじらはんどさんのリンクからejdict-hand-utf8.zipをダウンロード&解凍をして、プロジェクト配下にejdict-hand-utf-8.txtを配置する

無料 英和辞書データ ダウンロード - ブラウザで使えるWeb便利ツール
ブラウザ上で手軽に使える便利ツール

ejdict.pyを以下のように作成する

import re

dict_file='./ejdict-hand-utf8.txt'

while True:
    print('正規表現を入力[q]で終了>>')
    re_str=input()
    if re_str =='':continue
    if re_str =='q':break

    with open(dict_file,'r',encoding='utf-8') as f:
        cnt=0
        while True:
            line = f.readline()
            if not line: break
            word = line.split('\t')[0]
            if re.fullmatch(re_str,word):
                print(word)
                cnt+=1
                if cnt > 20: break
python
スポンサーリンク
シェアする
mjpurinをフォローする
ジョイタスネット

コメント

タイトルとURLをコピーしました