Python – 正規表現(Regex)でメールアドレス
正規表現(Regex/Regular expression)は難しいものではありません。説明を読んで、いくつかの単純な例題で試せば、学習も容易です。
正規表現という名称は、正規文字列(regular string)の判定に使われたことに由来します。つまり、「はい、入力された文字列は規則に従っていますので、返します」か、「この文字列は規則に従っていないので、破棄します」かどちらかの返答が必ずできるのです。これは、膨大な文書を迅速に走査して、電話番号や電子メールアドレスを探すときなどに、とても役立ちます。
1. Regex(正規表現)基礎
- 文字「a」を1個以上書く。
- この文字の後に文字「b」を正確に5個追加する。
- この文字の後に文字「c」を偶数個追加する。
- 末尾に文字「d」または「e」を書く。
この規則に従う文字列は、「aaaabbbbbccccd」、「aabbbbbcc」のようなものです(無限個の組合せが可能です)。
正規表現は、これらの規則を簡略に表記したものです。例えば、上に記した一連の規則が次のような正規表現で表されます。
aa*bbbbb(cc)*(d|e)
この文字列は、最初は少し難しく見えるかもしれませんが、要素に分解すればわかりやすいでしょう。
aa*
文字aを書いて、a*(aスターと読みます)が続きます。この意味は、0個も含めて「任意個のa」です。このようにして、文字aが少なくとも1つ書かれたのを保証します。
(cc)*
偶数個というものは、対で処理できる。そこで、2つのcを書いて、括弧で囲み、その後にアスタリスクを書くと、cの対が任意個数(0個の対も意味することに注意)という意味になります。
*(d|e)*
2つの式の間に縦棒を書くと、「前者または後者」を意味します。この場合は、「dまたはe」です。このようにして、正確にどちらかの文字を保証します。
2. Regexを試す
正規表現の書き方を学ぶときには、試行錯誤して、どう働くかの感覚を身に付けることが重要です。
コードエディタで数行書いて、正規表現が期待通りに働くかどうか確かめるために、
Regex Pal:http://regexpal.com/
のようなWebサイトで、自分の書いた正規表現をその場で試すことができます。
3. Pythonでよく使われるRegex(正規表現)
よく使われる正規表現の記号を、簡単な説明と例とともにまとめています。この表は、完全なものではありませんし、前にも述べたように、プログラミング言語によって多少の違いがあり得ます。しかし、この12の記号は、Pythonで最もよく使われていますし、ほとんどの文字列型で検索と収集に用いることができます。
記号 | 意味 | 例 | 合致する文字列例 |
---|---|---|---|
* | 先行する文字、部分式、角括弧文字の0個以上と合致 | a*b* | aaaaaaaa , aaabbbbb , bbbbbb |
+ | 先行する文字、部分式、角括弧文字の1個以上と合致 | a+b+ | aaaaaaaab , aaabbbbb , abbbbbb |
[] | 角括弧内の任意の文字(すなわち、「この中からどれでも」)と合致 | [A-Z]* | APPLE , CAPITALS , QWERTY |
() | まとめた部分式(正規表現の「演算順序」で最初に評価される) | (a*b)* | aaabaab , abaaab , ababaaaaab |
{ m , n } | 先行する文字、部分式、角括弧文字をm 個からn 個(両端含む)と合致 | a{2,3}b{2,3} | aabbb , aaabbb , aabb |
[^] | 角括弧にない文字と合致 | [^A-Z]* | apple , lowercase , qwerty |
| | 「| 」で区切られた文字や部分式のどちらかに合致(縦棒、または「パイプ記号」で大文字の「i」ではないことに注意) | b(a|i|e)d | bad , bid , bed |
. | 任意の1文字(記号、数字、空白などを含む)と合致 | b.d | bad , bzd , b$d , b d |
^ | 文字または部分式が文字列の先頭にあることを示す | ^a | apple , asdf , a |
\ | エスケープ文字(「特別な」文字を字面で使うことができる) | \^\|\\ | ^|\ |
$ | 正規表現の末尾として使う。「文字列の終わりまでこれと合致」を意味する。これがないと、すべての正規表現はデファクトで「.* 」を末尾に持ち、文字列の先頭部分と合致することを意味する。これは、^ 記号と同様なものと考えてよい。 | [A-Z]*[a-z]*$ | ABCabc , zzzyx , Bob |
?! | 「含まない」。この珍しい記号対は、その直後の文字(または正規表現)が、より大きな文字列のその位置に現れるべきではないことを意味する。これは使い方が難しい。その文字が文字列の他の部分に現れるかもしれないからだ。文字が一切現れないようにするには、^ と$ とを両端に組み合わせて使う。 | ^((?![A-Z]).)*$ | no-caps-here, $ymb0ls a4e f!ne |
正規表現の古典的な例が、メールアドレスの識別で見られます。
電子メールアドレスの正確な規則はメールサーバごとに少し違いますが、一般規則を作ることができます。規則に対応する正規表現を2列目に示します。
規則 | 正規表現 |
---|---|
規則1 メールアドレスの最初の部分は少なくとも次を含む。大文字、小文字、数字0-9、ピリオド( . )、プラス記号(+)、下線(_ )。 | [A-Za-z0-9\._+]+ 正規表現は強力だ。例えば、「A-Z」が「A-Zの大文字どれでも」を意味する。可能な文字列と記号を角括弧(丸括弧でなく)に入れることで、「角括弧にあるもののどれでも」よいことを示す。 + 記号が「これらの文字がいくつあってもよいが、少なくとも1つはあること」を意味していることに注意。 |
規則2 この後は、メールアドレスは @ 記号を含む | @ 文字通り。 @ 記号は中間にあって、正確に1つだけ。 |
規則3 メールアドレスは、少なくとも1つの大文字か小文字を含まねばならない。 | [A-Za-z]+ @ 記号の後のドメイン名の最初の部分は文字だけを使う。少なくとも1文字はなければならない。 |
規則4 ピリオド( . )が続く | . トップレベルドメインの前にピリオド( . )がいる。バックスラッシュをエスケープ文字として使う。 |
規則5 最後に、メールアドレスは末尾にcom, org, edu, netのいずれかが付く(実際には、多くのトップレベルドメイン名があるが、例題にはこれで十分なはず)。 | (com|org|edu|net) メールアドレスの第2の部分でピリオドの後にくる可能な文字列のリストを示す。 |
すべての規則をまとめると、次の正規表現になります。
[A-Za-z0-9._+]+@[A-Za-z]+.(com|org|edu|net)
まとめ
今回は、Python – 正規表現(Regex)でメールアドレスでした。どんな正規表現でも初めから書くときには、目標文字列がどんなものかを具体的に示す手順をリストアップするのがよいでしょう。
限界ぎりぎりの特別な場合に注意を払うことです。例えば、電話番号を識別する場合、国番号や内線番号を考慮したでしょうか。