📘
正規表現「RegExp」を用途別にまとめてみた
はじめに
よく使うけど、個人的にあまりちゃんと理解できていなかった正規表現(Regular Expression)。
正規表現は、例えばFlutterでユーザーが入力したメールアドレスのフォーマットを検証したり、文字列から特定のパターンを抽出したいときに便利です。
改めて、Dartにおける正規表現の使い方を用途別に深掘りしてみました。
そもそも正規表現とは
正規表現は、特定の文字列パターンを表現する方法です。
例えば、メールアドレスのフォーマットチェックなどに使われます。
↓こんなの
void main() {
bool regExp = isValidEmail("hogehoge@gmail.com");
print(regExp); // true
}
bool isValidEmail(String email) {
return RegExp(r'^[\w\.-]+@[\w\.-]+\.\w+$').hasMatch(email);
}
用途1:特定の文字列が含まれているかチェックしたい
void main() {
String input = "Flutter is awesome!";
RegExp regExp = RegExp(r"Flutter");
print(regExp.hasMatch(input)); // true
}
RegExp(r"パターン") のように、rを使ってraw文字列で表記します。
用途2:メールアドレスのフォーマットをチェックしたい
bool isValidEmail(String email) {
return RegExp(r'^[\w\.-]+@[\w\.-]+\.\w+$').hasMatch(email);
}
| 表記 | 意味 |
|---|---|
| [] | いずれかの文字を1文字 |
| \w | 英数字とアンダースコア(a-zA-Z0-9_)を意味する |
| . | .を文字として扱う |
| - | -を文字として扱う |
| + | 1文字以上の繰り返し |
| $ | 行の末尾 |
[\w\.-]
これは 「英数字・アンダースコア・ドット・ハイフン」のいずれかを1文字以上含む文字列であることをチェックしています。
上記にマッチする文字列
○ user@example.com
○ user@example.com
× invalid@com
× @example.com
用途3:文字列が3文字の数字のみかチェックしたい
bool isThreeDigitNumber(String input) {
return RegExp(r'^\d{3}$').hasMatch(input);
}
| 表記 | 意味 |
|---|---|
| ^ | 行の先頭 |
| \d | 数字(0〜9)1文字(dはdigitの略らしい) |
| {3} | 直前のパターン(ここでは\d)を3回繰り返す |
| $ | 行の末尾 |
上記にマッチする文字列
○ '123'
× '12'
× '1234'
× 'abc'
用途4:携帯番号のフォーマットチェックをしたい
bool isValidPhoneNumber(String number) {
return RegExp(r'^0[789]0-\d{4}-\d{4}$').hasMatch(number);
}
| 表記 | 意味 |
|---|---|
| ^ | 行の先頭 |
| [789] | 7,8,9のいずれかであること |
| - | -を文字として扱う |
| \d{4} | 数字4桁であること |
| $ | 行の末尾 |
上記にマッチする文字列
○ '090-1234-5678'
× '060-1234-5678'
× '0901234-5678'
× '090-1234-567'
用途5:パスワードのフォーマットをチェックしたい
条件:「英字を1つ以上含み、かつ数字を1つ以上含み、全体として英数字のみで構成され、8文字以上である文字列」
bool isValidPassword(String password) {
return RegExp(r'^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d{8,}$').hasMatch(password);
}
| 表記 | 意味 |
|---|---|
| ^ | 行の先頭 |
| (?=.*[A-Za-z]) | 肯定先読み:「どこかに英字が含まれている」ことを確認 |
| (?=.*\d) | 肯定先読み:「どこかに数字が含まれている」ことを確認 |
| [A-Za-z\d]{8,} | 「英字または数字を8文字以上」 |
| $ | 行の末尾 |
上記にマッチする文字列
○ "abc12345"
× "abc123"
× "abcdefghi"
× "12345678"
まとめ
今までこの暗号のような文字列について深く考えたことがありませんでしたが、何をしているのかがなんとなく理解できるようになりました。
Discussion