メインコンテンツまでスキップ

RegExp

RegExpは正規表現のためのJavaScriptの組み込みクラスです。組み込みなだけあり、リテラルでの表記とコンストラクタを利用した表記の2通りがあります。
このページではJavaScriptのRegExp型について触れ、正規表現そのものについては直接触れません。

リテラルでのRegExp型は/で検索したい文字を囲み、最後にフラグを書きます。一方コンストラクタでは第1引数が検索したい文字で、第2引数がフラグになります。次のRegExp型は同じものを指しています。

ts
const regexp1 = /0(8|9)0-[0-9]{4}-[0-9]{4}/g;
const regexp2 = new RegExp("0(8|9)0-[0-9]{4}-[0-9]{4}", "g");
ts
const regexp1 = /0(8|9)0-[0-9]{4}-[0-9]{4}/g;
const regexp2 = new RegExp("0(8|9)0-[0-9]{4}-[0-9]{4}", "g");

このとき\については、コンストラクタを利用する場合はふたつ書く必要があります。次のRegExp型は同じものを指します。

ts
const regexp1 = /0(8|9)0-\d{4}-\d{4}/g;
const regexp2 = new RegExp("0(8|9)0-\\d{4}-\\d{4}", "g");
ts
const regexp1 = /0(8|9)0-\d{4}-\d{4}/g;
const regexp2 = new RegExp("0(8|9)0-\\d{4}-\\d{4}", "g");

とくに、バックスラッシュ\1文字を検索したい場合、コンストラクタでは\\\\と4文字書く必要があるので注意してください。

動的に検索する対象を切り替えたい場合はコンストラクタを利用し、特に理由がなければリテラル記法を利用するのがよいでしょう。

RegExpの操作

文字列に一致するものがあるかどうかを検査する - Regexp.prototype.test()

第1引数の文字列を正規表現で検索するにはtestメソッドを使います。
一致するものがある場合はtrue、そうでない場合はfalseを返します。

ts
const regex = /日/;
 
console.log(regex.test("日曜日"));
true
ts
const regex = /日/;
 
console.log(regex.test("日曜日"));
true

文字列で一致するものの検索をする - Regexp.prototype.exec()

第1引数の文字列を正規表現で検索し、結果をstring[]型で返します。
string[]の0番目はマッチした文字列を、1番目以降はキャプチャグループを設定したときに限りパターンにマッチした文字列を取得します。
一致するものがない場合はnullを返します。

ts
const regex = /(.日).*(.日).*(.日).*(.日).*(.日)/;
const results = regex.exec("03月01日は日曜日で祝日、晴れの日でした。");
 
console.log(results);
["1日は日曜日で祝日、晴れの日", "1日", "は日", "曜日", "祝日", "の日"]
ts
const regex = /(.日).*(.日).*(.日).*(.日).*(.日)/;
const results = regex.exec("03月01日は日曜日で祝日、晴れの日でした。");
 
console.log(results);
["1日は日曜日で祝日、晴れの日", "1日", "は日", "曜日", "祝日", "の日"]

string型のメソッドでRegExpを使うメソッド

文字列を検索する - String.prototype.match()

文字列をRegExpで検索します。Regexp.prototype.exec()と同じように使うことができます。
結果はstring[]型で返り、0番目はマッチした文字列を、1番目以降はキャプチャグループを設定したときにパターンにマッチした文字列を取得します。
一致するものがない場合はnullを返します。

ts
const regex = /(.日).*(.日).*(.日).*(.日).*(.日)/;
const str = "03月01日は日曜日で祝日、晴れの日でした。";
 
console.log(str.match(regex));
["1日は日曜日で祝日、晴れの日", "1日", "は日", "曜日", "祝日", "の日"]
ts
const regex = /(.日).*(.日).*(.日).*(.日).*(.日)/;
const str = "03月01日は日曜日で祝日、晴れの日でした。";
 
console.log(str.match(regex));
["1日は日曜日で祝日、晴れの日", "1日", "は日", "曜日", "祝日", "の日"]

String.prototype.match()で注意すること

RegExpにgのフラグがついている場合、完全一致した文字列の配列を返し、キャプチャグループを返さなくなります。

ts
const regex1 = /(.日)/;
const regex2 = /(.日)/g;
const str = "03月01日は日曜日で祝日、晴れの日でした。";
 
console.log(str.match(regex1));
["1日", "1日"]
console.log(str.match(regex2));
["1日", "は日", "曜日", "祝日", "の日"]
ts
const regex1 = /(.日)/;
const regex2 = /(.日)/g;
const str = "03月01日は日曜日で祝日、晴れの日でした。";
 
console.log(str.match(regex1));
["1日", "1日"]
console.log(str.match(regex2));
["1日", "は日", "曜日", "祝日", "の日"]

Named capturing groupsについて

キャプチャグループで名前を指定することができるNamed capturing groupsがありますが、残念ながらTypeScriptとの相性はよくありません。
次の例ではNamed capturing groupsとしてprefwardにはそれぞれ"静岡県""磐田市"がマッチしますがTypeScriptはそのプロパティに値が設定されていることを保証しません。値の取得はオプショナルチェーンを使うとよいでしょう。

ts
const regex = /(?<pref>.+[都|道|府|県])(?<ward>.+[市|区|町|村])/gu;
const str = "静岡県磐田市気子島";
const match = regex.exec(str);
 
console.log(match?.groups?.pref);
"静岡県"
console.log(match?.groups?.ward);
"磐田市"
 
ts
const regex = /(?<pref>.+[都|道|府|県])(?<ward>.+[市|区|町|村])/gu;
const str = "静岡県磐田市気子島";
const match = regex.exec(str);
 
console.log(match?.groups?.pref);
"静岡県"
console.log(match?.groups?.ward);
"磐田市"
 

📄️ オプショナルチェーン

JavaScriptのオプショナルチェーン?.は、オブジェクトの参照がnullやundefinedの場合でも、エラーを起こさずにプロパティを参照できる安全な方法です。