お役立ち情報

Pythonの正規表現とは?使い方や種類について解説

Pythonの正規表現

Pythonだけではありませんが、プログラミング言語には正規表現というものがあります。正規表現とは数値や文字や記号の羅列の規則性を抽出して表記したものです。数学の公式のようなものですが、そこまで難しくはありません。

なので、数学が苦手、公式は嫌い、といった方でも安心して読み進めていただければと思います。単に文字列の集まりの法則を表記する際のルールなので、混乱することはないかと思います。直感的に理解できるようなものです。

正規表現の具体例

正規表現の定義だけではイメージしづらいかと思うので、具体例を紹介します。

よくある例ですが、たとえば郵便番号は以下のように0~9までの数字3桁、ハイフン、0~9までの数字4桁、という構成になっています。実在しないありえない郵便番号ですが、以下のようなものです。

123-4567

実際に上記のような郵便番号が存在するわけではありませんが、フォームとしてはこのようになっています。これを正規表現で表すと、以下のようになります。

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

おそらく、説明しなくても直感的にそういうことか、と勘付かれる方が多いのではないでしょうか。正規表現という言い方をすると難しく感じられますが、実際には上記のようなものです。

まず最初の[]のなかは、0~9の数字を意味しています。郵便番号は0~9の数字が入るため、このようになります。

次に、{}のなかは桁数を表しています。郵便番号の前半部分は3桁なので、3が入っています。

間のハイフンはそのままで、後半部分も同様に0~9の数字が入り、それが4桁なので{}のなかは4になっています。

正規表現を使った文字列の置換

正規表現は文字列を定義づけて抽出することができますが、置換することもできます。文字列の置換方法はいくつかあるので、紹介していきます。

sub関数による正規表現の文字列置換

最初にsub関数を使った文字列置換の方法を紹介します。sub関数の公式は以下です。

re.sub(正規表現, “置換する文字列”, 置換対象の文字列)

reモジュールのsub関数を使用し、正規表現、置換する文字列、置換対象の文字列をそれぞれ引数で指定していきます。それでは、次に具体的なサンプルコードを紹介します。

import re

text = "パイソンを使ってプログラミングを行います。"
text_mod = re.sub('パイソン', "Python", text)
print (text_mod)

上記のソースコードを実行すると、以下のようにコンソール出力されます。

Pythonを使ってプログラミングを行います。

改行を含む文字列を置換する方法

上で紹介したサンプルコードでは1行だけを置き換えましたが、複数行置き換えることも可能です。しかし上で紹介した方法をそのまま使うと1行目だけが置換されてしまうため、別のコードを使用する必要があります。以下がサンプルコードです。

import re

text = """\
070-1234-5678 Tokyo
080-1234-5678 Chiba
090-1234-5678 Saitama
"""
text_mod = re.sub('^[0-9]{3}-[0-9]{4}-[0-9]{4}',"***-****-****",text, flags=re.MULTILINE)
print (text_mod)

上記のソースコードを実行すると、以下のようにコンソール出力されます。

***-****-**** Tokyo
***-****-**** Chiba
***-****-**** Saitama

電話番号の数字がすべてアスタリスクに置換されました。

ユーザーが入力した文字を暗号化して桁数だけ見せたいときによく用いられるコードです。ポイントとしては、re.subの第四引数にre.MULTILINEを指定していることでしょう。

このre.MULTILINEが何かというと、改行したタイミングで行の先頭と見なすためのコードです。第四引数を指定しないと、二行目以降の電話番号がアスタリスクに変換されません。

テストをするのでまず起こりえないことではありますが、たとえば暗号化しなければならない個人情報の二行目以降を暗号化せずにそのまま表記するようなことがあると個人情報の流出につながります。

正規表現で一致した文字列を後方参照で置換

正規表現を置換する際、一般的には再度正規表現を一から書くのが一般的です。しかし、もともとある正規表現を少し書き換えたいというケースもあるでしょう。たとえば7桁の数字をハイフンでつないで郵便番号に書き換えたい場合、以下のように置き換えることを最初に思いつくかと思います。

[0-9]{3})([0-9]{4}→[0-9]{3})-([0-9]{4}

間に矢印を入れて書き直せば良いのですが、元の正規表現を活かして書き換えることも可能です。これを後方参照と呼びますが、サンプルコードとしては以下のようになります。

import re

text="""\
1234567
3334444
9876543
"""
text_mod = re.sub(r'([0-9]{3})([0-9]{4})', r'\1-\2', text, flags=re.MULTILINE)
print (text_mod)

上記のコードを実行すると、以下のようにコンソール出力されます。

123-4567
333-4444
987-6543

間にハイフンが入りました。

上記のソースコードで着目すべきポイントは、sub関数の第二引数です。’\1-\2’となっていますが、\1と\2はそれぞれ第一引数の前半部分と後半部分を表しています。

つまり、([0-9]{3})が\1と対応し、([0-9]{4})が\2と対応しているのです。そして\1と\2の間にはハイフンが入っているため、最終的に3桁と4桁で区切った郵便番号のフォーマットに変換されました。

後方参照は使う場面を探すのが難しいかもしれませんが、使いこなせるとソースコードの冗長さを防ぐことができます。また、今回の例だとありえない話ではありますが、たとえば郵便番号の前半部分が4桁に変わったとしても後方参照を使用すれば書き換える部分が少なく済みます。

上記のソースコードだと正規表現の置換前と置換後が自動的に連動した方が良いシステムなので、後方参照にすると万が一書き換えられた際にも利便性が高いです。

正規表現を使った文字列の抽出

正規表現を使った文字列抽出には複数の方法がありますが、match関数を使用した方法を紹介します。match関数は文字列の先頭に抽出ワードが存在するかどうかを判定する関数で、第一引数に抽出する正規表現、第二引数に検索対象の文字列を指定します。サンプルコードは以下です。

import re
address = "123-4567 "
postCode = re.match('[0-9]{3}-[0-9]{4}' , address)
print (postCode)

上記のソースコードを実行すると、以下のようにコンソール出力されます。

<_sre.SRE_Match object; span=(0, 8), match=’123-4567′>

文字列の前半部分が一致したため、matchした値を返しています。正規表現を使用した関数は他にもいろいろありますが、まずは正規表現が何か、どのように扱うのかを把握できれば良いかと思います。

具体的なコードは後々いろいろと調べたり、実装に必要な場合はピンポイントで特定のコードを探して記述すれば効率的です。

キャリアカウンセリングのプロとして
あなたに合った案件をご案内します。

まずはお気軽にお問い合わせください!

イメージ