正規表現のきほん
このレッスンで分かること
- 正規表現は、文字そのものではなく「形」で探すための記法です
matchは当たらなかったとき、空配列ではなくnullを返します
includes では「4 桁の数字」を探せない
入門のフォームで書いた入力チェックは、value.length と includes の 2 つで足りていました。空かどうか、あの文字が入っているか。見ていたのはそこまでです。
学習ログの本文から年号だけを抜き出したい、と言われた瞬間に手が止まります。includes("2026") は 2026 という決め打ちの文字を探すもので、「4 桁の数字」という形を探すものではないからです。
正規表現は、その形を書くための記法です。スラッシュで挟んで書きます。
JavaScript
const pattern = /\d{4}/;
console.log(pattern.test("2026年に公開しました")); // true
console.log(pattern.test("今年に公開しました")); // false/\d{4}/ は「数字がちょうど 4 個並んでいる箇所」という意味です。test は、その形が文字列のどこかにあれば true を返します。
種類と個数の 2 つで読む
パターンは、1 文字ぶんの種類を表す書き方と、それが何個続くかを表す書き方の組み合わせでできています。この 2 つが読めれば、たいていのパターンは読めます。
| 書き方 | 意味 |
|---|---|
\d | 数字 1 文字 |
\w | 半角英数字とアンダースコア 1 文字 |
\s | 空白、タブ、改行のどれか 1 文字 |
[a-z] | 角かっこの中のどれか 1 文字。範囲でも書ける |
[^ab] | 角かっこの中以外の 1 文字 |
. | 改行以外のどれか 1 文字 |
+ | 直前のものが 1 個以上 |
* | 直前のものが 0 個以上 |
{3} | 直前のものがちょうど 3 個 |
{2,4} | 直前のものが 2 個以上 4 個以下 |
\d を大文字にした \D は「数字以外」です。\W \S も同じ関係になります。
JavaScript
console.log(/\d+/.test("作品は12件")); // true
console.log(/[A-Z]{2,}/.test("HTML")); // true
console.log(/[A-Z]{2,}/.test("Html")); // false3 行目が false になるのは、Html に大文字が 1 個しか続いていないからです。「2 個以上」という指定がそのまま効いています。縦棒はどちらか一方という意味で、丸かっこで範囲を区切れます。
JavaScript
console.log("公開日と更新日".match(/(公開|更新)日/g)); // ["公開日", "更新日"]当たった文字を取り出す
test は当たるかどうかしか返しません。当たった文字そのものが欲しいときは match を使います。末尾の g を付けないと、最初の 1 件で探すのをやめます。
JavaScript
const text = "AB12 と CD34 の 2 件";
console.log(text.match(/[A-Z]{2}\d{2}/)); // ["AB12", index: 0, ...]
console.log(text.match(/[A-Z]{2}\d{2}/g)); // ["AB12", "CD34"]g はスラッシュの後ろに続けて書くフラグです。もう 1 つよく使う i は、大文字と小文字を区別しなくします。
ここがこのレッスンでいちばん踏みやすい落とし穴です。match は当たらなかったとき、空配列ではなく null を返します。
JavaScript
console.log("学習ログ".match(/[A-Z]{2}\d{2}/g)); // null
console.log(["12", "34"].map(Number)); // [12, 34]返り値をそのまま map や length につなぐと、Cannot read properties of null で落ちます。使う前に null かどうかを確かめます。取り出せるのは "12" のような文字列なので、数値にしたいときは 2 行目のように Number へ通します。
よくある間違い
.をそのまま書く — 正規表現の.は「どれか 1 文字」です。/example.com/はexampleXcomにも当たります。ピリオドそのものを探すなら/example\.com/と書きます- 形を見なくてよい場面で持ち出す — 決まった語が入っているかは
includes、始まりと終わりはstartsWithとendsWithで足ります。title.includes("プロフィール")を/プロフィール/.test(title)に書き換えても、読みにくくなるだけです
要件
- 関数名は extractYears、引数は文字列の text を 1 つ受け取る
- 4 桁の数字に当たる部分をすべて取り出し、出てきた順に並べる
- 戻り値は数値の配列にする。文字列のままにしない
- 1 つも見つからないときは空配列を返す