入力を検証する
このレッスンで分かること
^と$で挟むと、一部ではなく文字列の全体を縛れます- メールアドレスの正しさは、正規表現だけでは判定できません
郵便番号の欄に「あ1234い」が通ってしまう
前の回の /\d{4}/ は「4 個並んだ数字がどこかにある」という意味でした。探すぶんにはこれでよかったのですが、検証に使うと、通してはいけないものが通ります。
JavaScript
console.log(/\d{4}/.test("あ1234い")); // true文字列の先頭を表す ^ と、末尾を表す $ で挟むと、「全体がこの形であること」になります。
JavaScript
console.log(/^\d{4}$/.test("あ1234い")); // false
console.log(/^\d{4}$/.test("1234")); // true
console.log(/^\d{3}-\d{4}$/.test("150-0001")); // true
console.log(/^\d{3}-\d{4}$/.test("1500001")); // false検証で使うパターンは、ほぼ必ず ^ で始まり $ で終わります。逆に言えば、^ と $ の無い検証用パターンを見かけたら、まず疑ってよい場所です。
^は角かっこの中では「以外」を意味しました。[^abc]と^abcは別物です。角かっこの外に出てきた^は先頭を表す、と覚えると混ざりません。
空白だけの入力は length では弾けない
入門のフォームでは name.length === 0 で空を弾きました。ところが、半角スペースだけを入れられると通ってしまいます。
JavaScript
console.log(" ".length === 0); // false 通ってしまう\s は空白文字 1 個、* は 0 個以上なので、/^\s*$/ は「先頭から末尾まで空白文字しか無い」を表します。空文字列も 0 個として当たるので、これ 1 本で空とスペースだけの両方を弾けます。
JavaScript
const blank = /^\s*$/;
console.log(blank.test("")); // true
console.log(blank.test(" ")); // true
console.log(blank.test("山田 太郎")); // falseハイフンの有無のように、あってもなくてもよい部分は ? で表します。? は 0 個か 1 個という意味なので、/^\d{3}-?\d{4}$/ と書けば両方の書き方を通せます。
メールアドレスは、形しか見ない
ここは正直に書いておきます。メールアドレスの正しさを正規表現だけで判定することはできません。
理由は 2 つあります。1 つは仕様が想像よりはるかに複雑で、引用符やコメントまで許しているため、仕様どおりに書くと数百文字になり、誰にも読めなくなることです。もう 1 つは、形が合っていても、そのアドレスが実在するとは限らないことです。taro@example.com は形として完璧ですが、届くかどうかは送ってみないと分かりません。
だから実務では 2 段階に分けます。
| 段階 | 何をするか |
|---|---|
| 入力時 | 明らかな打ち間違いを弾く。@ が無い、ドットが無い、空白が入っている |
| 送信後 | 確認メールを送り、リンクを踏んでもらって初めて有効とみなす |
正規表現が担当するのは 1 段目だけです。[^\s@]+ は「空白でも @ でもない文字が 1 個以上」なので、これを @ とドットでつなげば、「アットマークがちょうど 1 個あって、その後ろにドットがある」ところまでを短く書けます。それ以上は見ません。
検証は厳しくするほど、正しい入力を弾く危険が上がります。弾かれた利用者は原因が分からないので、そのまま離脱します。迷ったらゆるいほうに倒すのが定石です。
よくある間違い
gを付けた正規表現をtestで使い回す —g付きの正規表現オブジェクトは「次にどこから探すか」を内部に持っていて、testが当たるたびにそれを進めます。関数の外に置いて使い回すと、2 回目の呼び出しが前回の続きから探し始め、同じ引数なのにfalseになります。検証にgは要らないので、付けないのがいちばんです- 空文字列を弾けているつもりになる —
+は 1 個以上なので空文字列を弾けますが、*は 0 個以上なので通します。/^\w*$/.test("")はtrueです
要件
- 関数名は validateContact、引数は { name, email } の形のオブジェクトを 1 つ受け取る
- name が空文字列または空白文字だけなら「お名前を入力してください」を入れる
- email が /^[^\s@]+@[^\s@]+.[^\s@]+$/ に当たらなければ「メールアドレスの形式が正しくありません」を入れる
- 戻り値は文字列の配列。両方に問題があれば name のメッセージを先に、問題が無ければ空配列を返す