Flutterで正規表現を用いたemailのvalidationを実装

image

この記事は、【 可茂IT塾 Advent Calendar 2021 】の8日目の記事です。

はじめに

Flutterでメールアドレスの形式が正しいかどうかを判定する際に、正規表現を用いたvalidationを実装する機会がありました。
実装自体はサクッとできるのですが、意味を理解していなかったので、詳細まで解説していきたいと思います。
実装だけしたい場合は、以下のコードをコピペでOKです。

var email = "makumaaku@makumaaku.com";
bool emailValid = RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+").hasMatch(email);

この正規表現は、こちらの記事を参考にしています。

正規表現を用いたemailのvalidationを解説

以下では、上記のFlutterでの正規表現を使ったemailのvalidationを分解して解説していきます。

r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+"

この文字列の意味が理解できることだゴールですね。

チェックポイント1

r"..."
これで...の中の文字列は、生の文字列になります。
\nなども改行ではなく、文字列となります。

チェックポイント2

^
行の先頭を意味する。 ^hogeの場合は、行頭がhogeから始まる文字列を示しています。

チェックポイント3

[...]
指定した文字列...の中のいずれかと一致しているものを指す。

[abc]の場合、aまたは、bまたは、cを表します。

チェックポイント4

a-zA-Z0-9
a-z ・・・aからzまでのいずれかの文字列
A-Z ・・・AからZまでのいずれかの文字列
0-9 ・・・0から9までのいずれかの文字列

これらは連結可能なので、a-zA-Z0-9はa~z,A~Z,0~9のいずれかに当てはまる文字列を表します。

チェックポイント5

[...]
チェックポイント3で登場した[ ]ですが、[ ]の中では、^+などのメタ文字は普通の文字として認識されます。
本来.はなんでも良い1文字を表しますが、[ ]の中では.という文字列扱いになります。

チェックポイント6

[...^...]
[ ]の中で2番目以降に^がある場合は、文字として認識されます。
[ ]の中で、^が先頭にある場合は、直後の文字の否定になります。(チェックポイント5の例外)
例外がある分ややこしくなりますが、 今回の例では、[ ]の中に入っている^は普通の文字を表しています。

チェックポイント7

+
+の直前の文字列が1つ以上続くものを示します。 maaku+の場合、maakuuuuuuuuuなど、maakに加えて、直前の文字列uが1つ以上の文字列を表します。

チェックポイント8

\. 今までに登場した、^,+などのメタ文字は、\.,\+とすることで、メタ文字でなく、単なる文字列扱いになります。 なので、\..という文字を表していることになります。

チェックポイントを踏まえvalidationの正規表現を解説

r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+"

文字に起こすと、以下のようになります。

  1. a~z,A~Z,0~9,.,!,#,$,%,&,',*,+,-,/,=,?,^,_,`,{,|,},~のいずれかの文字列が、
  2. 1つ以上並んでいるものが先頭に来ていて、
  3. @とa~z,A~Z,0~9のいずれかが1文字以上並んでいて、
  4. .とa~z,A~Zの文字列が1文字以上並んでいる。

少し長いですね^^; 以下は、1~4部分が実際のコードのどの部分を指しているかです。

  1. [a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]
  2. ^[...]+
  3. @[a-zA-Z0-9]+
  4. \.[a-zA-Z]+

1番の部分は、[a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]でいい気がします。

最後に

いかがでしょうか。
Flutterでのemailのvalidationの実装方法に加え、正規表現もある程度理解できましたか。
いくつかある規則性を覚えさえすれば、あとは当てはめるだけなので、思ったよりもシンプルかもしれませんね。
参考になれば幸いです。

参考記事

https://userweb.mnet.ne.jp/nakama/