👻

正規表現を用いてメールアドレスの形式かを確認する

に公開2

メールアドレスかどうかを判断するには、RegExpクラスのhasMatch関数を用いる。

正規表現(regular expression)とは、文字列のマッチパターンを表現する方法です。 正規表現を使うと、テキスト・データ・レコード内の特定のパターンにマッチする文字列を探し出して修正することができ、テキスト・データを操作するユーティリティ・プログラムやプログラミング言語でよく使われます。


RegExp regExp = RegExp(
      r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$',
    );
    bool isValid = regExp.hasMatch(source);

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

\w : 大文字/小文字の英字、数字、アンダースコアに一致。"[A-Za-z0-9]"と同意。
[\w] : 英字、数字、アンダースコアのどれか一文字

+ : 直前の文字の1文字以上の繰り返しにマッチする。

^ : 行の先頭を表します。正規表現が^で始まる場合、それは対象の文字列が行の先頭にあることを意味します。例えば、^abcは、abcが行の先頭にある場合にマッチします。

$ : 行の末尾を表します。正規表現が$で終わる場合、それは対象の文字列が行の末尾にあることを意味します。例えば、xyz$は、xyzが行の末尾にある場合にマッチします。

正規表現の例

r'^[\w]+' //大文字、小文字の英字、数字、アンダースコアで組まれた文字列

用いた正規表現

メールアドレスのユーザ名部分(左側)に対応した正規表現
英字、数字、アンダースコアとw以降に記載された記号を組み合わせて作られた文字列に対応

[\w-+.!#$%&'*/=?^`{|}~]+

メールアドレスのドメイン名部分に対応した正規表現
英字、数字、アンダースコア、ハイフンで組まれた文字列の後、ドットで始まり英字、数字、アンダースコア、ハイフンで組まれた文字列が一回以上繰り返す

[\w-]+(\.[\w-]+)+

最後にドルを置くことで、文字列の最後が必ずドットで始まり英字、数字、アンダースコア、ハイフンで組まれた文字列で終わることを定義できる。ドルがない場合だと、[\w-]+(.[\w-]+)+
このパターンがあれば、他にどんな記号があっても許可される

(\.[\w-]+)+$

完成型

r"^[\w-+.!#$%&'*/=?^`{|}~]+@[\w-]+(\.[\w-]+)+$"

組まれた正規表現の動作を確認するために用いたコード

  List<String> emailSamples = [
    'john.doe@example.com',
    'john_doe@example.com',
    'john-doe@example.com',
    'john.doe123@example.com',
    'john@example.co.jp',
    'john@example-domain.com',
    'john@example.subdomain.co.uk',
    'john+spam@example.com',
    'john.doe@example.museum',
  ];
  
  RegExp regExp = RegExp(
      r"^[\w-+.!#$%&'*/=?^`{|}~]+@[\w-]+(\.[\w-]+)+$",
      caseSensitive: false, //大文字と小文字を区別するか
      multiLine: false, //複数行に対応するか
    );
  
  // リスト内の各メールアドレスを処理する例
  for (String email in emailSamples) {
    bool isValid = regExp.hasMatch(email);
    print('$email: $isValid');
  }

参考記事

https://api.dart.dev/stable/2.16.1/dart-core/RegExp-class.html
https://www.kamo-it.org/blog/regular_expression/

Dart regular expressions have the same syntax and semantics as JavaScript regular expressions.

https://qiita.com/iLLviA/items/b6bf680cd2408edd050f

Discussion

mipsparcmipsparc

こんにちは。
結論から言うと、この記事は「メールアドレスっぽい文字列」かどうかを確認するのにはいいのかもしれませんが、実際には送信できないメールアドレスもすり抜けます。
たとえば foo..bar@example.com は、RFCに違反するため送受信ができないケースが多いですが、この正規用言では防がれていません。
そのため、RFCに規定されたメールアドレスかどうかをさらに厳しく判定しないと、実用上問題があります。

しょうゆしょうゆ

ご助言ありがとうございます。
検証レベルでいうと最低限メールアドレスっぽいかどうかを判断基準として作成しました。
私自体メールアドレスをどのような組合せで作成出来るかあやふやだという点もあり、このように作成しました。
mipsparcさんの指摘通り、実用上の問題が出かねないので、その点に対して追記しておきます。
ありがとうございました。