超初心者向け 正規表現 Regex Regular Expression

正規表現は、文字列の検索パターンを表現するための記法です。英語では、`Regular Expression`、`Regex`と呼ばれたりします。言語やツールにより多少の違いがあります。

正規表現については、[ドットインストール](https://dotinstall.com/lessons/basic_regexp_v2)で勉強することができます。この記事は、その内容を備忘録的に、メモしています。復習やチートシートのとして、利用いただけたら幸いです。

1. [メタ文字を使う](#メタ文字を使う)
1. [文字種](#文字種)
1. [量指定子](#量指定子)
1. [](#)
1. [](#)
1. 

文字をそのまま検索で使うことを`リテラル`と言います。

## メタ文字を使う
### `.`を使う
メタ文字を使うことで高度の検索をすることができます。`.`は、`改行を除く任意の1文字`という意味です。
例えば、`bat` `cat` `hat` `jet`という文字列があった場合、`.at`とすると`jet`以外の文字列が、検索対象となります。

### `\`を使う
`This is a pen.`の`.`を検索対象としたい場合、`.`を使うと全ての文字が検索対象となってしまいます。`\`(バックスラッシュ)を使って、`\.`とすると、メタ文字をエスケープすることができ、`.`を`リテラル`として検索対象にすることができます。
`\`を検索対象にする場合は、`\\`として、検索します。

## 文字種
- `\d` -> `0-9`
- `\D` -> `\d 以外`
- `\w` -> `a-z, A-Z, 0-9, _`
- `\W` -> `\w 以外`
- `\s` -> `スペース, タブ, 改行など`
- `\S` -> `\s 以外`

### 数字を置換する
```text:例題
ito, 03-0123-4567
sato, 03-1234-5678
tanaka, 03-9876-5432
```
上記の電話番号の部分を検索対象にして、`xx-xxxx-xxxx`で置換したい場合は、
```text:Find
\d\d-\d\d\d\d-\d\d\d\d
```
```text:Replace
xx-xxxx-xxxx
```
としてあげると、
```text:結果
ito, xx-xxxx-xxxx
sato, xx-xxxx-xxxx
tanaka, xx-xxxx-xxxx
```
とすることができます。

### 文字列を置換する
今度は、下記の`tanaka`の`t`以外を伏せ字にしてみます。

```text:例題
ito, 03-0123-4567
sato, 03-1234-5678
tanaka, 03-9876-5432
```
`t`で始まる6文字の文字列なので、
```text:Find
t\w\w\w\w\w
```
```text:Replace
t*****
```
とすると、
```text:結果
ito, xx-xxxx-xxxx
sato, xx-xxxx-xxxx
t*****, xx-xxxx-xxxx
```
と置換する事ができます。

## 量指定子
量指定子を使うと、`\d\d\d...`と続くものを省略して書く事ができるので便利です。
`{n}`を使うと、`n個`、{min,max}`を使うと`min以上、max以下`、`{min,}`は、`min以上`という意味で連続するものの数を指定して、書く事ができます。

例えば、下記のような電話番号を指定するには、
```text:電話番号
03-0123-4567
```
```text:例
\d{2}-\d{4}-\d{4}
```
のように検索する事ができます。
また下記の2つの番号を検索する場合は、
```text:電話番号
03-0123-4567
090-0123-4567
```
```text:例
\d{2,3}-\d{4}-\d{4}
```
とすると、両方に一致させる事ができます。
このように、量指定子を使うと簡単に書く事ができて便利です。
下記の、名前の4文字以上を検索対象にしたい場合は、
```text:例題
ito, 03-0123-4567
sato, 03-1234-5678
tanaka, 03-9876-5432
```
```text:例
\w{4,}
```
すると、`sato`と`tanaka`に一致させる事ができます。

## `?` `+` `*`
`?`は`{0,1}`、 `+`は`{1,}` 、`*`は`{0,}`という意味です。もしこの意味がわからなければ、一つ上のセクションの量指定子を見てみてください。

下記の２つの番号に一致させたい場合は、
```text:例
03-1234-5678
0312345678
```
```text:regex
\d{2}-?\d{4}-?\d{4}
```
とするとどちにも一致させることができます。

また下記の２つの番号に一致させたい場合は、
```text:例
TEL03-1234-5678
T0312345678
```
```text:regex
\w+\d{2}-?\d{4}-?\d{4}
```
とするとどちにも一致させることができます。

下記の4つの番号に一致させたい場合は、
```text:例
03-1234-5678
0312345678
TEL03-1234-5678
T0312345678
```
```text:regex
\w*\d{2}-?\d{4}-?\d{4}
```
とすると全てに一致させることができます。

次のような文字列を検索する場合は、
```text:例
"apple", "apples", "pineapple"
```
```text:regex
".+?" 
```
とすると一致させることができます。
この場合の`?`は先に説明した意味とは異なる意味を持っているようです。

## アンカー
アンカー配置を指定するのに使います。`^`は`行の先頭`、`$`は`行の末尾`、`\b`は`単語の境界`を意味するメタ文字です。
`^`は、次のように、行頭の数値に一致させたい場合で、他にも数値がある場合に使えます。
```text:例
1 sato 6
2 ito 9
3 tanaka 8
4 saito 7
```
```text:regex
^\d
```
とすると一致させることができます。
また、
```text:regex
\d$
```
とすると末尾の数値に一致させることができます。

検索に、`ito`と入力すると`ito`と`saito`の一部の`ito`にも一致してしまいますが、単語としての`ito`のみに一致させたい場合は、以下のようにすると単語としての`ito`のみに一致させることができます。
```text:regex
\bito\b
```

## 選択子
`abc|123`とすると`abc`または、`123`という意味になる。
下記の文字列に一致させたい場合、
```text:例
example.com
example.net
```
下記の２つの書き方で一致させることができる
```text:regex
example\.com|example\.net
example\.(com|net)
```
## 文字クラスを使う
下記の文字列に一致させたい場合、
```text:例
bat cat hat
```
下記の２つの書き方で一致させることもできるが、
```text:regex
bat|cat|hat
(b|c|h)at
```
`[]`を使って、
```text:regex
[bch]at
```
としても一致させることができる
`[abc]`は、a,b,cのどれか1文字という意味になる

## `^`で否定の表現
`[`の直後で、`^`を使うと否定の表現になる。
下記の文字列で、`cat`以外に一致させたい場合
```text:例
bat cat hat　eat
```
下記のようにすると一致させることができる
```text:regex
[^c]at
```
また、`hat`のみに一致させたい場合は、
```text:regex
[^cb]at
```
としても一致させることができる。

## `-`で範囲指定
例えば`[A-F]` とすると`A`から`F`という意味になる。
下記のリストの`A`から`F`に一致させたい場合は、
```text:例
A1
Q31
N18
C5
E32
L4
```
下記のようにすると一致させることができる
```text:regex
[A-F]\d+
```
この範囲指定を使うときは、文字コード表を参考にするといいみたいです。
下記に参考の表を貼っておきます。もしもっといいものがあれば教えてください。
[ASCII](https://www-creators.com/archives/4304)

## 文字クラスのルールに慣れる
下記のような電話番号があり、全てに一致させたい場合
```text:例
03^1234^5678
03-1234-5678
03.1234.5678
```
```text:regex
^\d{2}[^-.]
```
としてしまうと、`[`の直後に`^`が来てしまっているので、否定の意味になってしまう。`\`を使って、エスケープすることができるが、
すると、`-`が範囲を指定するメタ文字として認識されてしまいます。なので、　また`\`エスケープします。

## 文字クラス内でのルール
他にもエスケープするものや、順番によってはエスケープしないものなど、状況によっても変わってきます。
`[]`内では、`]`もエスケープが必要で、`[\]]`のように書いてエスケープします。
`\`も`[\\]`のようにエスケープします。
上記の`[^-.]`についてですが、`[]`内では、`.`は、リテラルなので、エスケープする必要がありません。また、`[-.^]`の順番で書いた場合、`-`は範囲を表さず、`^`は、`[`の直後ではないのでエスケープする必要がありません。

最終的に以上のルールを踏まえて、一致させると下記のようになります。

```text:regex
^\d{2}[-.^]\d{4}[-.^]\d{4}[-.^]$
```

## タブと改行
`\t`で`タブ`を表す。`改行`は、`OS`によって異なり、`Windows`は`\r\n`、`V9`までの`macOS`は`\r`、`Uinux`と`V10`以降の`macOS`は`\n`で`改行`を表す。選択肢を使って`\r\n|\r|\n`とすると、全ての`OS`に対応させることができる。
下記の文字列の改行を一つに統一したい場合は、
```text:例
abc

a
b


c
```
下記のようにして一個以上の改行に一致させて、
```text:regex
n\+
```
`n\`で置き換えると
```text:regex
abc
a
b
c
```
上記のように改行が一つに統一される。

## キャプチャを使って置換する
`()`を使うと、括弧内の内容を記憶することができる。
例えば、下記のようなリストがあって、それを`HTML`のリンクタグにしたい場合、
```text:例
google,https://google.com
example, https://example.com
```
下記のようにすると一致させることができる。
```text:regex
.+,\s?.+
```
`()`を使って記憶させて、
```text:regex
(.+),\s?(.+)
```
`$1,$2`を使って、置き換えると、
```text:regex
<a href="$2">$1</a>
```
```text:regex
<a href="https://google.com">google</a>
<a href="https://example.com">example</a>
```
となり、リストを`HTML`のリンクに置き換えることができました。

## 後方参照

下記のような文字列があり、前の数字が後ろの数字と一致しているかを調べたい場合、
```text:例
3, 8, 5, 4, 4, 5, 4, 1, 1, 5, 3, 3
```
`()`と`\1`を使って、
```text:regex
(\d),\s\1
```
とすると、`4, 4`、`1, 1`、`3, 3`などの連続している数字に一致させることができる。
`\1`は、後方参照するものが多ければ、`\1, \2, \3, ...`と使うことができる。

以上が、ドットインストールで勉強できる内容です。
下記のURLより、勉強することができます。

ドットインストール
[dotinstall.com](https://dotinstall.com/lessons/basic_regexp_v2)

　
[RegExr](https://regexr.com/):Regexを勉強するのに便利な有名なサイトです。ドットインストールの勉強をこのサイトでするのもおすすめです。

https://www.youtube.com/watch?v=rhzKDrUiJVk

by [Web Dev Simplified](https://www.youtube.com/@WebDevSimplified)
[Regexr Website](https://regexr.com) を使ったとてもわかりやすい解説です。Regexrを使ったことがない人は、ぜひ使ってみてください。Regexを勉強するための一番有名なサイトです。説明なども読むことができるのでとても便利です。

https://www.youtube.com/watch?v=ZfQFUJhPqMM

https://www.youtube.com/watch?v=EiRGUNrz9MY

## Regular Expressions Tutorial
https://www.youtube.com/playlist?list=PL4cUxeGkcC9g6m_6Sld9Q4jzqdqHd2HiD

[Regular Expressions 101](https://regex101.com/)
[Course files](https://github.com/iamshaunjp/regex-playlist)
### Simple RegEx Patterns
[Literal, Regex Flag, global, insensitive](https://www.youtube.com/watch?v=uaepGvA-iK4&list=PL4cUxeGkcC9g6m_6Sld9Q4jzqdqHd2HiD&index=2)


https://www.youtube.com/watch?v=sa-TUpSx1JA

https://www.w3schools.com/jsref/jsref_obj_regexp.asp