【Python】高度な文字列操作のための正規表現入門

  • URLをコピーしました!

正規表現が使えるようになると次のようなことができます。

ターゲットになる文字列を調べて…

  • 5文字の数字があれば取得
  • 文末の改行だけ削除
  • あるキーワードがあるかを検索

replacefind関数でも一応は実装できるものの煩雑なコードになりがちですが、正規表現ならスッキリ書けます。

最初は変わった書き方に面食らってしまうかもしれません。

でも正規表現はとてもパワフルなので、慣れてきた頃には文字列操作が得意になっているはずです。

終盤にご紹介する「肯定先読み」「肯定後読み」が使えるとできることが飛躍的に広がりますので頑張って習得しましょう!

【基本編】reライブラリのメソッド

Pythonで正規表現を扱うにはreライブラリを使います。

いくつかあるメソッドから僕がよく使うものを紹介します。ここではまずはどんなことができるか?を理解してほしいと思っています。

出だしから難しいことをすると心が折れてしまうので、本来は正規表現を使う部分に

「おはようございます。こんにちは。こんにちは。こんばんは。」

という文字列を入れて動作を確認しましょう。

サンプルコードの前にimport reを書いておいてください。

マッチする文字列があるかをチェック

txt = "おはようございます。こんにちは。こんにちは。こんばんは。"
ret = re.search(r'こんにちは。', txt)
print(ret)
# <re.Match object; span=(10, 16), match='こんにちは。'>

searchを使うと、正規表現で指定したパターンが文字列に含まれるかを調べられます。

文字列の一致があればマッチオブジェクトを、なければNoneを返します。

マッチする文字列が複数ある場合は最初の文字列だけが返されます。
すべての文字列を取得したい場合はfindallを使います。

マッチする文字列すべてをリストで取得

txt = "おはようございます。こんにちは。こんにちは。こんばんは。"
ret = re.findall(r'こんにちは。', txt)
print(ret)
# ['こんにちは。', 'こんにちは。']

findallは、正規表現にマッチしたすべての文字列をリストで取得します。

今回はtxtに2回「こんにちは。」が含まれているので、2つの「こんにちは」がリストに格納されました。

パターンに完全一致するかを確認

txt = "おはようございます。こんにちは。こんばんは。"
ret = re.fullmatch(r'おはようございます。こんにちは。こんばんは。', txt)
print(ret)
# <re.Match object; span=(0, 22), match='おはようございます。こんにちは。こんばんは。'>

fullmatchでは、正規表現パターンに完全にマッチした場合だけマッチオブジェクトを返します。

一文字でも違うパターンだった場合にはNoneを返します。

パターンに一致した文字列を置き換え

txt = "おはようございます。こんにちは。こんばんは。"
ret = re.sub(r'こんばんは。', 'おやすみ。', txt)
print(txt)
# おはようございます。こんにちは。おやすみ。

基本、replace関数のようなものだと思っていただいてOKです。

ただし正規表現でパターンを指定できるので、replace関数よりもより細かい文字列操作ができます。

マッチオブジェクトから文字列を取得

txt = "おはようございます。こんにちは。こんにちは。こんばんは。"
ret = re.search(r'こんにちは。', txt)
ret_txt = ret.group(0)
print(ret_txt)
# 'こんにちは。'

groupメソッドを使うと、マッチオブジェクトから文字列を取得できます。

グループに分けて部分的に文字列を取得

txt = "おはようございます。こんにちは。こんばんは。"
ret = re.search(r'(おはようございます。)(こんにちは。)(こんばんは。)', txt)
ret_0 = ret.group(0)
ret_1 = ret.group(1)
ret_2 = ret.group(2)
ret_3 = ret.group(3)

print(ret_0) # おはようございます。こんにちは。こんばんは。
print(ret_1) # おはようございます。
print(ret_2) # こんにちは。
print(ret_3) # こんばんは。

正規表現をタプルで囲ってグループを作ると、グループごとに文字列抽出ができます。

テキストを分割しつつ取得したい場合に便利です。

【実践編】正規表現の書き方

ここからは正規表現を使って文字列のパターンを指定する方法をご紹介します。

コードの動作を確認するために正規表現チェッカーを使うのがおすすめです。
正規表現で書いたパターンにマッチしてるかどうかをリアルタイムで画面表示してくれます。

» 参考:正規表現チェッカー|WWWクリエイターズ

文頭の1文字

txt = "名前"
ret = re.search(r'^.', txt)
print(ret)
# <re.Match object; span=(0, 1), match='名'>

文頭の1文字を取得する場合は^.と書きます。

これではちょっと分かりづらいので、一文字ずつ分割して考えましょう。

  • ^:文頭という位置を表す文字
  • .:改行以外の1文字

これより、「名前」という文字列の先頭一文字である「名」が取得できました。

文末の1文字

txt = "名前"
ret = re.search(r'.$', txt)
print(ret)
# <re.Match object; span=(1, 2), match='前'>

文末は$で表せるので、.$とすれば文末の1文字を取得できます。

すべての文字列

txt = "吾輩は猫である。名前はまだない。"
ret = re.search(r'.*', txt)
print(ret)
# <re.Match object; span=(0, 16), match='吾輩は猫である。名前はまだない。'>

*は直前の文字の0回以上の繰り返しを表します。

.*とすることで改行が出現するまですべての文字列を取得することになります。

改行コードを削除する

txt = "吾輩は猫である。\n名前はまだない。\n\nどこで生まれたかとんと検討もつかぬ。"
ret = re.sub(r'\n{1,}', '', txt)
print(ret)
# 吾輩は猫である。名前はまだない。どこで生まれたかとんと検討もつかぬ。

{1,}とすることで1回以上の繰り返しを表します。

ここでは「もし改行コード\nが1回以上現れたら空欄に置き換える(削除する)」ということになります。

特定の文字列をキーに開始位置を決める

txt = "吾輩は猫である。\n名前はまだない。\n\nどこで生まれたかとんと検討もつかぬ。"
ret = re.search(r'(?<=名前は).*', txt)
print(ret)
# <re.Match object; span=(12, 17), match='まだない。'>

(?<=文字列)とすると、「文字列」というワードの終わりを開始位置としてパターンを見つけられます。

つまり、(?<=名前は)とすると「名前は」という文字列の終わりが開始位置になり、その後に.*とすることで改行が現れるまでの文字列を全部取得することになります。

ここでは「まだない」が取得されるというわけです。

この書き方を「肯定先読み」といいます。

特定の文字列をキーに終了位置を決める

txt = "吾輩は猫である。\n名前はまだない。\n\nどこで生まれたかとんと検討もつかぬ。"
ret = re.search(r'.*(?=である)', txt)
print(ret)
# <re.Match object; span=(0, 4), match='吾輩は猫'>

今度は終了位置を決める方法で、(?=文字列)という風に使います。

ここでは「である」を探してきて、その直前までのパターンを見に行きます。

.*を指定していますから、「吾輩は猫」までが抽出されるというわけです。

この書き方を「肯定後読み」といいます。

【発展編】実務でよく使う正規表現コード

ここからは実務でよく使う正規表現コードを紹介します。

書き方に迷ったらこちらのコードをコピーしてお使いください!

郵便番号

^[0-9]{3}-[0-9]{4}$

ハイフンなしの7桁の場合は、正規表現の中のを削除してください。

電話番号

0[7-9]0-[0-9]{4}-[0-9]{4}

携帯電話番号の場合です。

固定電話や国際電話などは別途コードを用意する必要があります。

まとめ

本記事でご紹介したことが理解できれば、かなりの文字列操作は簡単にできるようになるはずです。

特に「肯定先読み」と「肯定後読み」がわかるとできることが飛躍的に増えますので、時間はかかってもいいのでぜひマスターしてみてください!

本ブログでは実務で使えるPythonテクニックを公開してますので、他の記事もぜひ覗いてみてください。

この記事が気に入ったら
フォローしてね!

シェアしてもらえると喜びます!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

Pythonを使ってプログラムを書くお仕事をしています。
業務自動化プログラムの作成が得意で、物販のお仕事をされている方や士業事務所様に業務効率化のツールをご提供させていただいております。
現在自力でWebサービスを作れるようになるべくDjangoを学習中。
お仕事のご相談はお気軽にご連絡ください。

コメント

コメントする