正規表現まとめ ＋ メールアドレスとURLの正規表現例

# はじめに

正規表現をよく使うようになったので備忘録

正規表現の表記法から、メールアドレス，URLまでをまとめてみた

とくにメールアドレスとURLを正規表現で表すのに時間がかかったものをまとめた

少しでも参考になればと…！

※当記事はPHPやJavaScriptなどのデリミタ```/スラッシュで囲う正規表現/```に対応していません
正規表現でスラッシュ(/)を使用する際、エスケープ文字を使用して```\/```などで対応してみてください

お品書きは下記の通り

* 正規表現とは
* 一般的な文字表現
* 基本的なメタキャラクタ
* 半角文字を対象にする記述方法
* バックスラッシュ(\\)について
* 正規表現を使った例
* さいごに

※メールアドレスとURLの正規表現だけ知りたい！という方は「正規表現を使った例」を見てください！

# 修正箇所

* 誤字を修正いたしました。(2020/06/13)
修正前：後述の表でまとめてあるが、**+** は…
修正後：前述の表でまとめてあるが、**+** は…

* メールアドレスの正規表現を変更いたしました。（2020/06/13)
URLの正規表現の変更に伴い、同様の修正を行ないました。
修正前：```[\w_\-.]+@[\w_\-.]+\.[A-Za-z]+```
修正後①：```[\w\-._]+@[\w\-._]+\.[A-Za-z]+```
修正後②：```[\w\-\._]+@[\w\-\._]+\.[A-Za-z]+```

* URLの正規表現を変更いたしました。 (2020/06/13)
変更リクエストを頂き、調査した結果、以下のような結果となりました。
編集リクエストをくださった方、ありがとうございました！
修正前：```https?://[\w!?/\+\-_~=;\.,*&@#$%\\(\)\'\[\]]+```
修正後①：```https?://[\w!?/+\-_~=;.,*&@#$%()'[\]]+```
修正後②：```https?://[\w!\?/\+\-_~=;\.,\*&@#\$%\(\)'\[\]]+```
詳しくは[こちらの記事][1]を参照してください

* URLの正規表現を変更いたしました。 (2019/12/06)

```
URLで使用できる記号を調べた結果以下のように追加＆削除を行なった。
削除文字：\ :
追加文字：! ' [ ]
```

# 正規表現とは
コンピュータに「数字が入力されたら出力して！」と命令したいときどうしますか？

おそらく、入力されたもののタイプが数値かどうか調べるのが多いかと思います

きっと、0 ~ 999999... をif文やswitch文で調べる方はいないでしょう

では、「この文字列がURLだったら出力して！」と命令するときはどうしましょう

もちろん、全世界のURLをリスト化して…という方もいないはずです

ここで便利なのが**正規表現**です

```正規表現(regular expressions)``` 文字列の特徴を表すパターンをコンピュータに教えてあげるための表現
regexp や regex とよく略されている

つまり、URLのパターンを正規表現でコンピュータに教えてあげれば、簡単にURLの判別を行なうことができるのです

正規表現便利！

しかし、いきなり正規表現を使ってURLを作るのは無理があるので、まずは正規表現一覧表を作ってみた

# 一般的な文字表現
以下から正規表現を表で紹介していく

バックスラッシュや改行など、正規表現上では表せないものを表したいときに使用

|表記法|意味||表記法|意味|
|:--|:--|:--|:--|:--|
|\ \|バックスラッシュ(\\)||\t|タブ文字|
|\a|警告||\c[char]|[char]に対する制御文字|
|\b|バックスペース||\O[octal]|8進数[octal]で表される文字|
|\f|改ページ||\x[hex]|2桁の16進数[hex]で表される文字|
|\n|改行||\x{[hex]}|16進数[hex]で表される文字|
|\r|キャリッジリターン(復帰)||\N{[name]}|[name]で指定される名前付き文字|

# 基本的なメタキャラクタ
**メタキャラクタ** ... 正規表現の中で特別な意味を持つ文字のこと

|メタキャラクタ|意味|例|マッチ|アンマッチ|
|:--|:--|:--|:--|:--|
|.|任意の一文字にマッチ|Q....|Qiita, QIITA, QQQQQ|qiita, Qita|
|*|直前の文字を0回以上繰り返したものにマッチ|Qi*ta|Qta, Qiita Qiiiita|Qi-ta|
|+|直前の文字を1回以上繰り返したものにマッチ|Qi+ta|Qita, Qiita|Qta, Qi-ta|
|{n}|直前の文字をn回繰り返したものにマッチ|Qi{2}ta|Qiita|Qita, Qiiita|
|{start_n,}|直前の文字を start_n 回以上繰り返したものにマッチ|Qi{2,}ta|Qiita, Qiiita|Qita|
|{start_n, end_n}|直前の文字を start_n 回以上 end_n 回以下繰り返したものにマッチ|Qi{2, 4}ta|Qiita, Qiiiita|Qiiiiita|
|?|直前の文字が0又は1回表示したものにマッチ|SEIKI?|SEIK, SEIKI|SEIKII|
|^|文字列の先頭がマッチ|^SEIKI|SEIKI HYOUGEN|THE SEIKI|
|$|文字列の末尾がマッチ|SEIKI$|THE SEIKI|SEIKI HYOUGEN|
|\b|境界（バックスペース）にマッチ|\bSEIKI\b|THE SEIKI HYOUGEN|THESEIKIHYOUGEN|
|\B|境界以外にマッチ|\BSEIKI\B|THESEIKIHYOUGEN|THE SEIKI HYOUGEN|
|[ABC]|A, B, C のいずれかにマッチ|[123]+|123, 11, 11321|100, abc|
|[^ABC]|A, B, C 以外にマッチ|[^123]+|560, 950, abc|100, 123|
|[A-Z]|A, B, ..., Z のいずれかにマッチ|[0-9]{10,}|0120000000|0120-000-000|
|[^A-Z]|A, B, ..., Z 以外にマッチ|[^a-z]+|QIITA|Qiita, qiita|
|[A-Za-z]|A, ..., Z, a, ..., z のいずれかにマッチ|[A-Za-z]{5}|Qiita, Apple, SEIKI|app01, TEST!|

※\bと\Bのように小文字を大文字にすると否定になるものがある
※[]と[^]のように **^** を使用すると否定になる

### そのほかのもの

``` AA|BB|CC ``` AA, BB, CC のいずれかにマッチ
例： 私は、(国語|数学|英語)が(好き|嫌い)です。
マッチ：　私は、数学が好きです。／私は、国語が嫌いです。
アンマッチ：　私は、算数が好きです。／私は、国語が得意だけど嫌いです。

# 半角文字を対象にする記述方法
今まで出てきたメタキャラクタを使った、**ショートカット**的なやつがある

ここでは、その記述方法を紹介する

|メタキャラクタ|意味|別の書き方|
|:--|:--|:--|
|\w|英数字|[A-Za-z0-9]|
|\W|英数字以外|[^A-Za-z0-9]|
|\d|数字|[0-9]|
|\D|数字以外|[^0-9]|
|\s|空白文字|[\t\n\r\f\x0B]|
|\S|空白文字以外|[^\t\n\r\f\x0B]|

※\x0B は 16進数の0Bの制御コード「VT(Vertical Tabulation) 垂直タブ」というものらしい

# バックスラッシュ(\\)について
正規表現例の前に、バックスラッシュについてまとめる

正規表現で 「〇 + 〇 = 〇」を表そうとした場合、**+** で不具合が生じてしまう

前述の表でまとめてあるが、**+** は直前の文字を1文字以上繰り返しという特殊な文字（メタキャラクタ）である

**+**を文字として入力したい場合**エスケープ文字**を使う

エスケープ文字を使用することにより「次の文字は特殊な文字じゃないよ！」と教えてくれる

バックスラッシュ(\\)がこのエスケープ文字にあたる

※バックスラッシュ以外に半角の円マークもエスケープ文字である

# 正規表現を使った例
では、上記で書いたメタキャラクタを使用して正規表現を作ってみます

正規表現をするには、まず特徴を考えてから部品ごとに組み合わせてあげるとやりやすい

### メールアドレス
まず、メールアドレスの特徴を考えます。

* @の前には英数字, _，-, . などが使用されている
* @の後ろはトップドメインとそれ以外のドメインに分けられる
* それ以外のドメインには、@の前と同じ文字が使用されている
* トップドメインにはアルファベットのみが使用されている

上記の特徴を踏まえて、作成した結果がこちら

**[\w\\-.\_]+@[\w\\-.\_]+\\.[A-Za-z]+**
（または**[\w\\-\\.\_]+@[\w\\-\\.\_]+\\.[A-Za-z]+**）

部分ごとに見ていましょう

>[\w\\-.\_]+@[\w\\-.\_]+

```[]+``` カッコ内の文字のいずれかが一文字以上という意味
```\w``` 英単語を構成する文字 つまり [A-Za-z0-9]
```-``` メタキャラクタで使用されているため、エスケープ
```_``` メタキャラクタでないため、そのまま入力
```.``` []内ではメタキャラクタでないため、そのまま入力

> \\.

トップドメインとそれ以外を分割するためのピリオド

> [A-Za-z]+

大文字，小文字アルファベットを1回以上

これらこれらを組み合わせると、メールアドレスの正規表現となる

### URL
例によって、まずURLの特徴を考えてみます。

* http から始まるものと https で始まるものがある
* そのあとに://~ と続いている
* 続きは、アルファベットや数字だけでなく、記号も出てくる（?,\,@,#,&などなど）

ということで上記の特徴を考えて作成した結果がこちら

**https?://[\w!?/+\\-_~;.,*&@#$%()'[\\]]+**
（または **https?://[\w!\\?/\\+\\-_~=;\\.,\\*&@#\$%\\(\\)'\\[\\]]+**）

部分ごとにみていく

> https?://

ここはわかりやすいでしょう

```?``` 「直前も文字が0回か1回」の意味

すなわち、以下のどちらかということがわかる

```
http://
https://
```

> [\w!?/+\\-_~=;.,*&@#$%()'[\\]]+

随分とごちゃごちゃしてますね…

言葉で表すと、「英数字又は記号が一文字以上」となる
一つ一つ見ていきましょう

```[]+``` カッコ内の文字のいずれかが一文字以上
```\w``` 英単語を構成する文字
```- ]```これらは[]内でメタキャラクタとして使用されているため、エスケープ
```! ? / _ ~ = ; , * & @ # $ %``` これらはメタキャラクタでないため、そのまま入力
```+ . ( ) ' [``` これらは[]内ではメタキャラクタでないため、そのまま入力

これらを全部組み合わせると、URLの正規表現となるのです( ˘ω˘ )

# さいごに
正規表現一覧とメールアドレス，URLの正規表現例をまとめた

正規表現を最初に見たときは、拒否反応が起きてました(笑)

正規表現をしっかりやろうと思って2,3ヶ月経ちましたが、正規表現を多用しております

むしろ正規表現が楽しくなっている変な自分がいますね…

ここで記述した正規表現以外の方法もあるので、自分に合った正規表現法を見つけてみてください(^▽^)/

[1]:https://qiita.com/str32/items/7ccfbeaaf42b92bf33e0