職案人

求職・歴史・仏教などについて掲載するつもりだが、自分の思いつきが多いブログだよ。適当に付き合って下さい。

JS--正規表現にマッチした文字列を取得する

2024年04月11日 | JavaScript

正規表示にマッチした文字列を取得する

【開発環境】
OS:Win11(64ビット)
VSCode1.72.2、
クロム

【execメソッドの使い方】
RegExp オブジェクトの exec メソッドは、対象となる文字列が正規表現とマッチした場合に、マッチした文字列を取得します
書式は次の通りです。

正規表現オブジェクト.exec(文字列)

引数に指定した文字列が正規表現とマッチした場合は、マッチした文字列が格納された配列を返します。マッチしなかった場合は null を返します。
戻り値の配列には
インデックス 0 の要素にパターン全体にマッチした文字列、
インデックス 1 以降の要素には設定したキャプチャグループで囲んだパターンにマッチした文字列が格納されます。
(キャプチャグループを設定していない場合はインデックス 1 以降の要素は存在しません)。

配列[0]  パターン全体にマッチした文字列
配列[1]  キャプチャグループ1にマッチした文字列
配列[2]  キャプチャグループ2にマッチした文字列
・・・
配列[n]  キャプチャグループnにマッチした文字列

サンプル

let regexp = /20\d{2}-\d{2}-\d{2}/;

let result1 = regexp.exec('Today is 2020-08-14');
console.log(result1[0]);実行
> 2020-08-14

let result2 = regexp.exec('Yesterday is 1998-12-07');
console.log(result2[0]);実行
> TypeError: Cannot read property '0' of null

文字列が正規表現にマッチした場合には、パターン全体がマッチした文字列がインデックス 0 の要素の値として格納された配列として受け取ります。

ただマッチしなかった場合には戻り値は null となり、 null に対してインデックス 0 の要素を取得しようとすると TypeError が発生します。

次のように null かどうかの条件分岐を追加するか例外処理を行ってください。

let regexp = /20\d{2}-\d{2}-\d{2}/;

let result = regexp.exec('Yesterday is 1998-12-07');
if (result !== null){
  console.log(result[0]);
}else{
  console.log('Not Match');
}
実行
> Not Match

【パターンにキャプチャグループが含まれる場合】
続いてパターンにキャプチャグループが含まれている場合です。
キャプチャグループを作成するには、パターンの中を括弧()で囲います。
するとキャプチャグループに設定したパターンの部分にマッチした文字列を取得することができます。

サンプル

let regexp = /(20\d{2})-(\d{2})-(\d{2})/;

let result = regexp.exec('Today is 2020-08-14');
for (let i = 0 ; i > i=0, match=2020-08-14
> i=1, match=2020
> i=2, match=08
> i=3, match=14

文字列が正規表現にマッチした場合は、戻り値として配列を受け取ります。インデックス 0 の要素にはパターン全体がマッチした文字列が格納される。
インデックス 1 以降の要素にはそれぞれキャプチャグループで囲まれたパターンにマッチした文字列が格納される。

【マッチした文字列の位置を参照する】
exec メソッドを実行して文字列が正規表現にマッチした場合、
マッチした文字列の先頭文字のインデックス戻り値として取得した配列の index プロパティに設定される。
そのため、 index プロパティを参照することでマッチした文字列の位置を参照することができます。
インデックスは対象の文字列の先頭文字が 0 、次の文字が 1 、と続いていきます。

サンプルコード

let regexp = /20\d{2}-\d{2}-\d{2}/;

let result = regexp.exec('Today is 2020-08-14');
console.log(result[0]);実行
> 2020-08-14
console.log(' lastIndex=' + result.index);実行
> lastIndex=9


対象の文字列の中で、正規表現にマッチした文字列の先頭文字のインデックスを参照することができました。

【グローバルフラグを設定してる場合】

パターンの最後に g を記述するとグローバルフラグを設定することができます。

/パターン/g

正規表現にグローバルフラグが設定されている場合
→exec メソッドを実行し文字列が正規表現にマッチすると、正規表現オブジェクトの lastIndex プロパティの値がマッチした文字列の次の文字のインデックスに設定されます。
(グローバルフラグが設定されていない場合は、 exec メソッドでマッチしたとしても lastIndex は 0 のままです)。

サンプル

let regexp = /[A-Z].+?day/g;
let str = 'Sunday Monday Tuesday';

let result = regexp.exec(str);
console.log(result[0]);実行> Sunday
console.log(' lastIndex=' + regexp.lastIndex);実行
> lastIndex=6

そのあとで同じ正規表現に対して同じ文字列を引数に指定して exec メソッドを実行すると、現在の lastIndex が示す文字列の位置から正規表現とマッチする文字列を取得します。再びマッチした場合は、改めて lastIndex プロパティの値が更新されます。

サンプル

let regexp = /[A-Z].+?day/g;
let str = 'Sunday Monday Tuesday';

let result = regexp.exec(str);
console.log(result[0]);実行
> Sunday
console.log(' lastIndex=' + regexp.lastIndex);実行
> lastIndex=6

result = regexp.exec(str);
console.log(result[0]);実行
> Monday
console.log(' lastIndex=' + regexp.lastIndex);実行
> lastIndex=13

exec メソッドを実行したときに正規表現にマッチしなかった場合には lastIndex は 0 に戻ります。

let regexp = /[A-Z].+?(day)/g;
let str = 'Sunday Monday Tuesday';

let result = regexp.exec(str);
while (result !== null){
  console.log(result[0]);
  console.log(result[1]);
  console.log(' lastIndex=' + regexp.lastIndex);

  result = regexp.exec(str);
}
console.log(' lastIndex=' + regexp.lastIndex);

>> Sunday
>> day
>> lastIndex=6
>> Monday
>> day
>> lastIndex=13
>> Tuesday
>> day
>> lastIndex=21
>> lastIndex=0

このようにグローバルフラグを設定することで、同じ文字列に対して正規表現が複数回マッチするかどうか確認しマッチした場合はその文字列を取得することができます。


コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« JS--文字列の規制表現のマッ... | トップ | JS--マッチした文字列のイン... »
最新の画像もっと見る

コメントを投稿

JavaScript」カテゴリの最新記事