正規表現（Regex）で ラクラク文字列検索・置換

## Hello Regex
膨大なプログラムファイルからsayHelloという名前のメソッドを見つけるにはどうすれば良いでしょうか。
ぱっと思いつく方法は```"sayHello"```で検索することです。しかしこれでは```function sayHelloWorld```や```var _SayHello```なんていう不必要な文字列もヒットしてしまいます。
ここで便利なのが正規表現を使った検索です。
```/[^0-9a-za-Z]sayHello[^0-9a-za-Z]/```で検索すれば、```function sayHello```や```obj.sayHello()```にヒットし、```function sayHello01```や```funtion runSayHello```にはヒットしないため、目的のメソッド定義と参照箇所だけを素早く見つけることができます。
この資料では、正規表現を使って自由自在に文字列を検索したり、置換したりする方法をお伝えします。

## 正規表現とは
正規表現は文字列のパターンを表現するための記法で、サクラエディタやVS Codeなどのエディタ、JavaやJSなどのプログラミング言語でファイルや文字列を検索したり置換したりするときに利用できます。
例えば、1234や2023といった0-9のいずれかの文字を4回繰り返すパターンは、正規表現では```/\d{4}/```または```/[0-9]{4}/```のように書きます。

一般的に、説明の際に普通の検索キーワードはダブルクオーテーションで囲って```"文字列"```のように表現しますが、正規表現の場合はスラッシュで囲って```/正規表現/```のように表現します。
テキストエディタで検索キーワードとして入力する際は両側のスラッシュは含めないでください。

## 正規表現をテキストエディタの検索機能で使う
### VS Code
検索キーワード入力欄のアイコン■*を押すと正規表現モードで検索できます。
アイコンAaを押すと大文字小文字が区別されるようになります。
![2023-02-01_19h31_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/09598599-f725-551b-ac3f-74462cfdea5a.png)

### サクラエディタ
正規表現にチェックを入れると正規表現モードで検索できます。
![2023-02-01_19h32_39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/f006c954-9ad3-2ba8-a584-6e423d5b69ae.png)


## 使えると便利なケース
### 日付を検索する
　検索キーワード：```/\d{4}/\d{1,2}/\d{1,2}/```
　　　　　　意味：4桁の数字、1または2桁の数字、1または2桁の数字がスラッシュ区切りになっている文字列
　一致する文字列：```2023/1/1``` ```2023/01/1``` ```2023/1/01``` ```2023/01/01```
一致しない文字列：```2023/001/001``` ```abcd/ef/gh```

### 日付の書式を変更する
　検索キーワード：```/(\d{4})/(\d{1,2})/(\d{1,2})/```
　置換キーワード：```"$1-$2-$3"```
　　　　　　意味：検索キーサードの丸括弧の中にヒットした値を置換キーワードで$nとして入れることができます
　　　　　置換前：2023/01/01
　　　　　置換後：2023-01-01

### ファイルの拡張子を取り出す
　検索キーワード：```/\.([a-zA-Z\d]+)$/```
　　　　　　意味：行末がピリオド＋アルファベットまはた数字の文字列
　　　　　　　　　（アルファベットまたは数字の部分を丸括弧でグルーピングして取っている）
　　　ファイル名：```hogehoge.fugafuga.piyppiyo.__.csv```
　　　　検索結果：```csv```
```JavaScript:sample.js
function getExtention(fileName) {
    return fileName.match(/\.([a-zA-Z\d]+)$/)[1];
}

console.log(getExtention('hogehoge.fugafuga.piyppiyo.__.csv'));
//=> 'csv'
```

### 変数名を検索する
　検索キーワード：```/[^\da-zA-Z_]|^variable[^\da-zA-Z_]|$/```
　　　　　　意味：前後がアルファベットやアンダーバーで始まらない文字列variable
　一致する文字列：```variable``` ```"variable"```
一致しない文字列：```_variable_``` ```avariableb```

### テーブル名にエイリアスのついていないSQLを検索する
　検索キーワード：```/FROM[\n\s]+[a-zA-Z][0-9a-zA-Z]*\s+[^a-zA-Z]/```
　一致する文字列：
```
SELECT
    ...
FROM
    tbl1, tbl2
WHERE
    ...
```
　一致しない文字列：
```
SELECT
    ...
FROM
    tbl1 t1
WHERE
    ...
```
## 試してみよう
１．VS Codeに以下のテキストを張り付けます。
```
hey
heyhey
heyheyhey
heyheyheyhey
heyheyheyheyhey
```

２．正規表現モードで検索キーワードに以下の文字列を入力してみましょう。※両側のスラッシュは含めない

heyが2回以上続く文字列：```/(hey){2}/```
heyが3回以上続く文字列：```/(hey){3}/```
heyが2回以上、4回以下続く文字列：```/(hey){2,4}/```

![2023-02-01_20h47_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/7dffd685-9533-a23d-1a35-d0427f5291d4.png)

## 記法
正規表現の解説記事はたくさんあるので、そちらに譲りましょう。
正規表現の解説サイト：https://city3939.com/regular-expression/
楽しいゲームサイト：https://www.regex-hunting.com/

ここでは、習うより慣れろ、で正規表現を一つ一つ自分で試しながら学習していきます。

## 問題集
### 初級 - Part1
使う正規表現：
行頭```^```
行末```$```
任意の一文字```.```
0回以上の繰り返し```*```
1回以上の繰り返し```+```
0または1回の繰り返し```?```

各正規表現の説明の後に練習問題がありますので、下記のテキストをテキストディタに張り付けて、正規表現を使って検索してみてください。
```TXT:sample.txt
apple
 apple
banana, apple

cloudy, sunny
sunny 
sunny, cloudy

I make
I shake
I take

ps
ops
oops

good morning
good moorning
goood mooorning

mew
meow
meoow

I was 5 minutes late
I was 10 minutes late
I was 100 minutes late
Sorry, I was 10 minutes late
I was 10 minutes late, sorry
```

資料の最後に答えがあります。
答え合わせしやすいように検索を試すエディタと自分の答えを張っておくエディタの二つを開いておくと良いでしょう。
![2023-02-02_13h30_49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/902e4706-a732-6c4b-0a1c-f01a5552ec36.png)


#### 【行頭】
行頭は```^```で表します。
例えば、行頭がabcで始まる文字列は```/^abc/```です。
**練習問題１：行頭がappleで始まる文字を検索してください**

#### 【行末】
行末は```$```で表します。
例えば、行末がabcで終わる文字列は```/abc$/```です。
**練習問題２：行末がsunnyで終わる文字を検索してください**

#### 【 任意の一文字】
任意の一文字は```.```で表します。
例えば、a●b（●は任意の一文字）という文字列は```/a.b/```です。
**練習問題３：```I ●ake```（●は任意の一文字）という文字列を検索してください**

#### 【0回以上の繰り返し】
0回以上の繰り返しは```*```で表します。
例えば、eが0回以上繰り返される文字列hy, hey, heeyなどは```/he*y/```です。
**練習問題４：```oooops```（oは1回以上繰り返される）という文字列を検索してください**

#### 【1回以上の繰り返し】
1回以上の繰り返しは```+```で表します。
例えば、heeellooo（eとoは1回以上の繰り返し）という文字列は```/he+llo+/```です。
**練習問題５：```goood mooorning```（oは2回以上の繰り返し）という文字列を検索してください**

#### 【0または1回の繰り返し】
0または1回の繰り返しは```?```で表します。
例えば、ac, abc（bは無いか、一文字だけある）という文字列は```/ab?c/```です。
**練習問題６：```meow```（oが無いか、oは一文字だけある）という文字列を検索してください**

#### ⇓ランクアップ問題⇓
**練習問題７：行頭Iで始まり行末がeで終わり、文字列中で0が1回以上繰り返される文字列を検索してください**

### 初級 - Part2
使う正規表現：
数字```\d```
いずれか一文字```[abc]```
アルファベット小文字```[a-z]```
アルファベット大文字```[A-Z]```
n回数繰り返し```{n}```
n回以上繰り返し```{n,}```
x回数以上、y回数以下繰り返し```{x,y}```

各正規表現の説明の後に練習問題がありますので、下記のテキストをテキストディタに張り付けて、正規表現を使って検索してみてください。
```TXT:sample.txt
Version:1-1-1
Version:1-10-1
Version:2-3-4

file1
file3
file8
file9

stick
stack
stock

lowercase a
lowercase z
lowercase A
lowercase Z


uppercase a
uppercase z
uppercase A
uppercase B
uppercase G
uppercase Y
uppercase Z

loooooooool
looooooooool
loooooooooool

wow
woow
wooow
woooow

cofe
coffe
coffee
cofffffee
coffeeee

```
#### 【数字】
数字は```\d```で表します。
例えば、file1～file9は```/file\d/```です。
**練習問題１：Version:●-●-●（●は任意の数字）という文字列を検索してください**
**練習問題２：```file●```（●は3-8の数字いずれか）という文字列を検索してください**

#### 【いずれか一文字】
いずれか一文字は```[abc]```で表します。
例えば、book, hookは```/[bh]ook/```です。
**練習問題３：```st●ck```（●はiまたはo）という文字列を検索してください**

#### 【アルファベット小文字】
アルファベット小文字は```[a-z]```で表します。
例えば、a1～z1は```/[a-z]1/```です。
**練習問題４：```lowercase ●```（●はアルファベット小文字）という文字列を検索してください**

#### 【アルファベット大文字】
アルファベット大文字は```[A-Z]```で表します。
例えば、a1～z1は```/[A-Z]1/```です。
**練習問題５：```uppercase ●```（●はB～Yのいずれか一文字）という文字列を検索してください**

#### 【n回数繰り返し】
n回数繰り返しは```{n}```で表します。
例えば、goooood（oが5つ）は```/go{5}d/```です。
**練習問題６：looooooooool （oが10個）という文字列を検索してください**

#### 【n回以上繰り返し】
n回以上繰り返しは```{n,}```で表します。
例えば、oops, ooooops（oは最低2回以上）は```/o{2,}ps/```です。
**練習問題７：wooow （oが最低3回以上）という文字列を検索してください**

#### 【x回数以上、y回数以下繰り返し】
x回数以上、y回数以下繰り返しは```{x,y}```で表します。
例えば、moon, moooon（oが2回以上4回以下繰り返す）は```/mo{2,4}n/```です。
**練習問題８：coffee （fとeは2回以上4回以下繰り返す）という文字列を検索してください**

## 答え
### 初級 - Part1
練習問題１：```/^apple/```
![2023-02-01_21h46_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/7f1469b3-509d-7f2b-cb75-8483ff840151.png)
練習問題２：```/sunny$/```
※6行目のsunnyは行末にスペースが入っているのでマッチしません
![2023-02-01_21h47_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/827e66d6-2052-2a3c-bb7e-1dd5b97e504f.png)
練習問題３：```/I .ake/```
![2023-02-01_21h46_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/7a32c548-ed80-18a1-4c8e-ccd0840ec289.png)
練習問題４：```/oo*ps/```
![2023-02-01_21h47_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/2a8cfea4-081e-13f1-d374-53df80ee5b66.png)

練習問題５：```/goo+d moo+rning/```
![2023-02-01_21h48_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/ef1db13b-26c7-398d-c302-d9a2557fbb94.png)

練習問題６：```/meo?w/```
![2023-02-02_11h39_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/4a72204c-5509-1a04-b770-eeca0a9f5fb0.png)

練習問題７：```/^I.*0+.*e$/```
![2023-02-02_09h10_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/78440e3f-a7d0-238a-1afe-4ce8fdd15377.png)

### 初級 - Part2
練習問題１：```/Version:\d-\d-\d/```
![2023-02-02_13h46_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/56ee5332-4f16-4aba-c6d9-c373f7571d90.png)

練習問題２：```/file[3-8]/```
![2023-02-02_13h46_56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/810aff17-5bfd-2ba4-3773-163191a48aa7.png)

練習問題３：```/st[io]ck/```
![2023-02-02_13h47_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/be11e7d7-ffb0-83d1-fc30-f2efe2f609cc.png)

練習問題４：```/lowercase [a-z]/```
※大文字小文字区別のモードにする
![2023-02-02_13h49_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/e25010a1-65d3-007c-bda3-2f8006b946dd.png)

練習問題５：```/uppercase [B-Y]/```
※大文字小文字区別のモードにする
![2023-02-02_13h50_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/c330e323-eee8-fa43-7ea8-75a78a5c162e.png)

練習問題６：```/lo{10}l/```
![2023-02-02_13h51_40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/2b947e0d-3343-6c4e-2caa-3a44e3641cce.png)

練習問題７：```/cof{2,4}e{2,4}/```
![2023-02-02_13h52_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86008/393cd715-5129-ce02-58d8-0d3e6652aa7f.png)