第10章 正規表現
基本的な構文と特殊文字
正規表現は様々な特殊文字を使ってパターンを表現します。
const regex = /abc/; // "abc"という文字列を検索する正規表現
const str = "abcdef";
console.log(str.match(regex)); // ["abc", index: 0, input: "abcdef", groups: undefined]
文字クラス
特定の種類の文字をマッチさせるためのパターン。
const digits = /\d/; // 任意の数字を検索する正規表現
const str2 = "apple123banana";
console.log(str2.match(digits)); // ["1", index: 5, input: "apple123banana", groups: undefined]
繰り返し
同じパターンの繰り返しを検索する。
const repeatedDigits = /\d+/; // 1回以上の数字の繰り返しを検索
const str3 = "apple123banana45";
console.log(str3.match(repeatedDigits)); // ["123", index: 5, input: "apple123banana45", groups: undefined]
選択、グループ化、参照
異なるパターンのいずれかをマッチさせる。
const colors = /red|blue|green/; // "red"、"blue"、または"green"を検索
const str4 = "apple red banana blue";
console.log(str4.match(colors)); // ["red", index: 6, input: "apple red banana blue", groups: undefined]
バウンダリマッチャー
文字列や単語の境界を指定してマッチさせる。
const wordBoundary = /\bapple\b/; // "apple"という単語全体を検索
const str5 = "apple pie pineapple";
console.log(str5.match(wordBoundary)); // ["apple", index: 0, input: "apple pie pineapple", groups: undefined]
フラグ
正規表現の振る舞いを変えるためのフラグ。
const caseInsensitive = /apple/i; // 大文字小文字を区別せず"apple"を検索
const str6 = "Apple pie";
console.log(str6.match(caseInsensitive)); // ["Apple", index: 0, input: "Apple pie", groups: undefined]
肯定的・否定的先読み
特定の文字が続くか、続かないかを基にマッチする。
const posLookahead = /q(?=u)/; // 'q'に直後に'u'が続く場所を検索
const str7 = "queen";
console.log(str7.match(posLookahead)); // ["q", index: 0, input: "queen", groups: undefined]
const negLookahead = /q(?!u)/; // 'q'に直後に'u'が続かない場所を検索
const str8 = "qatar";
console.log(str8.match(negLookahead)); // ["q", index: 0, input: "qatar", groups: undefined]
文字セットと否定文字セット
特定の文字セットの中から1文字をマッチさせる。否定文字セットは指定したセットの文字以外をマッチ。
const charset = /[aeiou]/; // 母音を検索
const str9 = "hello";
console.log(str9.match(charset)); // ["e", index: 1, input: "hello", groups: undefined]
const negCharset = /[^aeiou]/; // 母音以外を検索
console.log(str9.match(negCharset)); // ["h", index: 0, input: "hello", groups: undefined]
バックリファレンス
以前にマッチしたグループと同じ内容を再度マッチさせる。
const backRef = /(abc)\1/; // "abcabc"のような繰り返しを検索
const str10 = "abcabc";
console.log(str10.match(backRef)); // ["abcabc", "abc", index: 0, input: "abcabc", groups: undefined]
Unicode プロパティエスケープ
特定のUnicodeプロパティにマッチする文字を検索する。
const unicodeProp = /\p{Script=Hiragana}/u; // ひらがな文字を検索
const str11 = "こんにちは";
console.log(str11.match(unicodeProp)); // ["こ", index: 0, input: "こんにちは", groups: undefined]
マッチパターンの一覧(一部)
マッチパターン | 内容 |
---|---|
. | 任意の文字(改行文字を除く)にマッチ |
\d | 数字にマッチ([0-9]と同等) |
\D | 数字以外にマッチ([^0-9]と同等) |
\w | 単語構成文字([a-zA-Z0-9_]と同等)にマッチ |
\W | 単語構成文字以外にマッチ |
\s | 空白文字(スペース、タブ、改行、フォームフィード)にマッチ |
\S | 空白文字以外にマッチ |
\b | 単語の境界にマッチ |
\B | 単語の境界以外にマッチ |
^ | 文字列の先頭、または多行モードでの行の先頭にマッチ |
$ | 文字列の末尾、または多行モードでの行の末尾にマッチ |
n | n番目のキャプチャグループにマッチ |
[...] | 指定された文字のいずれか1文字にマッチ |
[^...] | 指定された文字以外のいずれか1文字にマッチ |
* | 直前の要素が0回以上続く場所にマッチ |
+ | 直前の要素が1回以上続く場所にマッチ |
? | 直前の要素が0回または1回続く場所にマッチ |
{n} | 直前の要素がn回続く場所にマッチ |
{n,} | 直前の要素がn回以上続く場所にマッチ |
{n,m} | 直前の要素がn回以上、m回以下続く場所にマッチ |
| | OR(または)演算子 |
( ...) | キャプチャグループ |
(?: ...) | キャプチャしないグループ |
(?= ...) | 肯定的先読み |
(?! ...) | 否定的先読み |
\\ | \自体にマッチ |
\t | タブにマッチ |
\r | キャリッジリターンにマッチ |
\n | 改行にマッチ |
\f | フォームフィードにマッチ |
\v | 垂直タブにマッチ |
\xNN | 16進数で指定された文字にマッチ (Nは0-9、a-fまたはA-F) |
\uNNNN | 16進数で指定されたUnicode文字にマッチ |
正規表現は非常に複雑で、このような基本的な特性から高度な特性まで多岐にわたります。これらのカテゴリをしっかりと理解することで、より高度なパターンマッチングを行うことができるようになります。
練習問題1.
以下の形式の電話番号をマッチさせる正規表現を書いてください。
形式: 0XX-XXXX-XXXX
Xは0-9の数字
012-3456-7890 // マッチする
0123-456-7890 // マッチしない
123-4567-8901 // マッチしない
012-3456-789A // マッチしない
練習問題2.
以下の基本的な条件を満たすメールアドレスをマッチさせる正規表現を書いてください。
ローカル部とドメイン部が"@"で区切られている
ローカル部は英数字とドット(.)が利用可能
ドメイン部は英数字とハイフン(-)、ドット(.)が利用可能で、最後はドット(.)に続く2〜6文字の英字)
test.email@example.com // マッチする
test.email@sub.example.com // マッチする
test.email@example // マッチしない
test.email@example.c // マッチしない
test.email@example.toolong // マッチしない
練習問題3.
以下の形式の日付をマッチさせる正規表現を書いてください。
形式: YYYY/MM/DD
Yは4桁の年 (例: 2023)
Mは1〜2桁の月 (例: 7 or 07)
Dは1〜2桁の日 (例: 5 or 05)
2023/7/5 // マッチする
2023/07/05 // マッチする
2023/7/35 // マッチしない (日にちが不正)
2023/13/05 // マッチしない (月が不正)
202/07/05 // マッチしない (年が3桁)