40 代おっさん GASの正規表現とRegExpオブジェクトについて学ぶ

## 本記事ついて

本記事は プログラミング初学者の私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。

## 正規表現とRegExpオブジェクト

### 正規表現

正規表現とは
文字列のパターンを表現するための方法
正規表現ｋにはa~z,0~9の通常文字、[]{}など特殊な役割を持つメタ文字の組み合わせパターンで表す。

正規表現は様々なパターンを表現できることからテキストの中から特定のパターンの文字列を検索、抽出、置換などの操作することができる。
正規表現パターンが円策して一致することをマッチすると言う

|文字|機能|正規表現の例|マッチする文字列の例|
|----|--------|------|----|
|.|任意の1文字|T.m こん..は|Tom,Tam,,T2m,こんにちは,こんばんは|
|*|直前の文字が0文字以上|Bo*b|Bb,Bob,Boob|
|+|直前の文字が1文字以上|Bo+b|Bob,Boob|
|?|直前の文字が0文字または1文字|Bo?b|Bb,Bob|
|?|(他のメタ文字の直後に指定した場合)最短の文字列とマッチするように制限する|||
|{n}|直前の文字をn文字|Bo{2}b|Boob|
|{n,}|直前の文字をn文字以上|Bo{1}b|Boob,Booob|
|{n,m}|直前の文字をn文字~m文字|Bo{1,2}b|Bob,Boob|
|｜|または|Tom｜Bob|Tom,Bob|
|[]|カッコ内のいずれかの一文字|T[aio]m,[0-9],[A-Z]|Tam,Tim,Tom,0,1,9,A,B,Z|
|{＾}|カッコ内の文字以外のいずれか1文字|T[^aio]m,[^0-9]|Tem,Tum,A,あ,ア|
|()|グループ|（(Bob)+私は(Bob｜Tom)|Bob,BobBob,私はBob,私はTom|
|^|行の先頭|||
|$|行の末尾|||
|\|メタ文字をエスケープ|\ \｜\ +|\　, +|
|\w|任意の半角英字、数字、アンダースコアの1文字([A-Za-z0-9]と同じ|\w|a,A,0|
|\b|数字の1文字([0-9]と同じ)|\b|0,1,9|
|\n|改行|||
|\r|復帰|||
|\t|タブ|||
|\s|空白文字（改行、復帰、タブを含む|||

### RegExpオブジェクト

RegExpオブジェクトとは
JavaScriptで正規表現を取り扱う機能を提供するもの

構文

```javascript
new RegExp('正規表現'[,'フラグ']
```

以下のようにスラッシュで囲むことによる正規表現リテラルで表記できる。
こちらが一般的

構文

```javascript
/正規表現/フラグ
```

＊ただし、スラッシュを使う場合は「\/」を使う。

|フラグ|説明|
|----|--------|
|g|グローバルサーチ、最初のマッチで止まらずにすべてのマッチを探す|
|i|大文字、小文字を区別しない|
|m|複数行を検索する|

RegExpオブジェクトのメンバー

|分類|メンバー|戻り値|説明|
|----|--------|------|----|
|メソッド|exec(str)|Array|文字列に対して正規表現で検索した結果を配列で返す|
|メソッド|test(str)|Boolean|文字列に対して正規表現で検索した結果を真偽値で返す|
|メソッド|toString()|String|正規表現を文字列で返す|
|プロパティ|lastIndex||次のマッチがはじまる位置|
|プロパティ|global||gフラグの真偽値|
|プロパティ|ignoreCase||iフラグの真偽値|
|プロパティ|multiline||mフラグの真偽値|
|プロパティ|source||正規表現パターンのテキスト部|

お試し

```javascript
function toshiki2() {
  const str = "私は利樹君です。　パパが大好きです。";

  const reg = /.利樹./g;
  console.log(reg.test(str));  

  console.log(reg.toString());
  console.log(reg.source);

  console.log(reg.global);
  console.log(reg.ignoreCase);
  console.log(reg.multiline)
}
```

文字列を検索する一つの方法としてexecメソッドがあります。

構文

```javascript
正規表現.exec(文字列)
```

先にコードを見てください

```javascript
function toshiki2() {
  const str = "私は利樹君です。　利樹はパパが大好きです。";
  const reg = /.で./g;
  
  console.log(reg.exec(str));
}
```

コンソールログは
18:05:01	情報	[ '君です',
  index: 4,
  input: '私は利樹君です。　利樹はパパが大好きです。',
  groups: undefined ]
になりました。

これはexecメソッドは、文字列を検索し正規表現にマッチした最初の文字列を１つだけ含む配列を返します。配列のインデックス０にマッチした文字列が格納されています。このとき、正規表現にｇフラグが付与されていれば、正規表現のIastlndexプロパティの値を、マッチした部分の次の位置を表す数値に置き換えます。ですから、再度execメソッドを実行した場合、前回の続きから検索を開始します。配列に含まれる。「index:4,input: '私は利樹君です。　利樹はパパが大好きです。」は、拡張プロパティをいい、その配列のプロパティとして取り出すことが出来る
マッチする文字列がない場合、execメソッドはnullを返します。

つぎに

```javascript
function toshiki2() {
  const str = "私は利樹君です。　利樹はパパが大好きです。";
  const reg = /.で./g;
  
  let result;
  while (result = reg.exec(str)) {
    console.log(`result: ${result[0]}, lastIndex: ${result.index}`);
  }
}
```

whileで回してマッチした文字列がある間繰り返しています。
これで2回目の要素も出てくると思います。

正規表現にマッチした文字列をまとめて収得する別の方法
matchメソッドを使う

構文

```javascript
文字列.match(正規表現)
```

```javascript
function toshiki2() {
  const str = "私は利樹君です。　利樹はパパが大好きです。";

  let reg = /.で./g;
  console.log(str.match(reg));//gフラグがあるのでマッチしたすべての文字列を返す
  

  reg = /.で./;
  console.log(str.match(reg));//gフラグがないので最初にマッチした文字列のみ返す
}
```

＊gフラグがない場合は厳密にいえば「最初の検索結果とサブマッチ文字列および拡張プロパティで構成された配列」を返している。
matchメソッドはlastIndexプロパティの書き換えがされないのでマッチした文字列の位置が知りたい場合はexecメソッドを使う。

正規表現でマッチした文字列の置換する場合はreplaceメソッドを使う

構文

```javascript
文字列.replace(正規表現, 置換後の文字列)
```

```javascript
function toshiki2() {
  const str = "私は利樹君です。　利樹はパパが大好きです。";
  let reg = /パパ/g;
  
  console.log(str.replace(reg, 'ママ'));
}
```

指定した文字列で対象の文字列を分割して配列で返すsplitメソッド

構文

```javascript
文字列.split(正規表現)
```

```javascript
function toshiki2() {
  const str = "私は、利樹君です。　利樹は、パパが、大好きです。";
  let reg = /[、。]/;
  
  console.log(str.split(reg));
}
```

## 参考資料

<https://www.amazon.co.jp/s?k=google+apps+script+%E5%AE%8C%E5%85%A8%E5%85%A5%E9%96%80&adgrpid=110264232688&gclid=CjwKCAiA9aKQBhBREiwAyGP5lSl7AJJLCvOEHb4wQgMlyqW1fll5X8GDTT_Rkd1_soUAyIPMXQr26hoClHEQAvD_BwE&hvadid=553833563682&hvdev=c&hvlocphy=1009076&hvnetw=g&hvqmt=b&hvrand=4378489642044417389&hvtargid=kwd-594191211348&hydadcr=4106_13159878&jp-ad-ap=0&tag=googhydr-22&ref=pd_sl_2x1owglv0s_b_p52>