苦手意識のあった正規表現について改めた

※4年前に別のナレッジベースへ投稿していたものを書き出しただけなので情報が古い可能性があります。

今まで正規表現を読む、使わなければ行けない場面では、その都度ググって適当な理解しかしていなかった。
おかげで「正規表現＝面倒くさくて難しいもの」という誤った認識をしてしまっていた。
今回、その苦手意識を払拭するために改めて調べた際のメモ。

正規表現とは
-----------------------------------

+ 文字列の集合を１つの文字列で表現する方法のひとつ
+ 主に文字列のパターンマッチングに使われる
+ その歴史は古く、1950年代、UNIXがリリースされる前まで遡る
+ 現在、多くの環境で使えるが、その実装は言語やアプリケーションで異なる
+ 正規表現を覚えることは、メタ文字セットによる表現の仕方を覚えるということ


パターンマッチとは
-----------------------------------

正規表現で表される文字列パターンに合致する文字列を探すこと。
正規表現を使うことで、文字列中のさまざまなパターンを記述できる。

+ 完全一致
+ 特定の単語を含む
+ 行頭に任意の文字列が付く
+ 行末に任意の文字列が付く
+ 任意の文字がｎ回連続する
+ 数字である
+ ハイフン区切りの日付形式となっている
+ などなど


正規表現でできること
-----------------------------------

正規表現自体は前述のとおり文字列の集合を１つの文字列で表現する方法だが、
この特徴を活かして次の用途によく使われる。

+ 文字列の検索
+ 文字列の置換

パターンマッチングの本領ともいえる検索はもちろんのこと、
検索した文字列に対して操作を行うことで置換ができる。

### ※正規表現＝置換ではない

正規表現がどういったものかを捉える際、
「検索するもの」とか、「置換するもの」として認識していると混乱を招きやすい。
正規表現はあくまで文字列のパターンを記述するものであり、
その結果として検索や置換に便利に使えるというだけである。


正規表現で覚えること
-----------------------------------

### 正規表現(メタ文字セット)の種類

実質覚えなければならない正規表現の仕様は以下の２つ。

+ Basic Regular Expressions (BRE)
+ Extended Regular Expressions (ERE)

GNU拡張やPerl拡張、Javascript拡張など、
様々な言語やアプリケーションで拡張された正規表現があるが、
基本的にそれらは殆どがEREのスーパーセットとなっている。
つまり大抵の拡張正規表現ではEREの記述で動くということになる。

とはいえ、それぞれのメタ文字セットはそれほど多くない。
また、BREとEREの違いは記述の際にエスケープ文字(\)が必要かどうかくらいで
ほとんど同じといえる。


正規表現の基本となる要素
-----------------------------------

### メタ文字

文字列の集合を表現するための特殊な意味を持った文字のこと。
組み合わせによって多種多様で複雑に見えるが、それ自体の種類はそれほど多くない。
正規表現で使えるメタ文字をまとめてメタ文字セットと呼ぶ。

### ブラケット(角括弧)

`[`~`]`のこと。文字クラスを表す。
正規表現のメタ文字は多く場合、ブラケットの外と中で意味が異なる。

### 文字クラス

文字の集合を指定するための方法。ブラケットで囲うことで文字クラスとなる。
集合の中のいずれか１文字がマッチングするという意味を表す。

+ [1234] なら1~4のいずれか１文字とマッチ
+ [abcd] ならa~dの小文字アルファベットいずれか１文字とマッチ
+ [0-9] なら0~9いずれかの１文字とマッチ
+ [A-Z] ならA~Zの大文字アルファベットいずれか１文字とマッチ


正規表現を理解する際のポイント
-----------------------------------

### 正規表現にはいくつかの種類がある

先にもあるとおり、正規表現(正確にはそのメタ文字セット)にはいくつかの種類がある。
正規表現を読む場合は、まずそれがどのメタ文字セットで書かれているのかを把握する必要がある。
また同様に正規表現を使えるユーティリティでは、
そのメタ文字セットで書く必要があるのかを確認する必要がある。

正規表現を使える現在のUNIXユーティリティは多くの場合BREがデフォルトとなっており、
コマンドラインオプションに-Eを含めるとEREが使えるようになる。

### メタ文字の意味は、メタ文字を使う場所によって意味が変わる

+ ブラケットの外
+ ブラケットの中
+ 置換構文(s/A/B)のBの部分

メタ文字は、ブラケットの外、ブラケットの中、
置換構文の置換文字列(s/A/B/構文のBの部分)で意味が変わるため
正規表現を読む場合は、この違いに気をつける。


メタ文字の一部(BRE)
-----------------------------------

| メタキャラクタ       | 説明                                                   |
|:---------------------|:-------------------------------------------------------|
| .                    | 任意の１文字にマッチする                               |
| [ ]                  | 括弧内に含まれる１文字にマッチする                     |
| [^ ]                 | 括弧内に含まれない１文字にマッチする                   |
| ^                    | 行の最初にマッチする                                   |
| $                    | 行の最後にマッチする                                   |
| *                    | 【繰返し指定子】０回以上の表現の繰り返しにマッチする   |
| BRE: \{m\}           | 【繰返し指定子】直前の要素のm回繰り返しにマッチする    |
| BRE: \{m,\}          | 【繰返し指定子】直前の要素のm回以上の繰り返しにマッチする。|
| BRE: \{m,n\}         | 【繰返し指定子】直前の要素のm回以上、n回以下の繰り返しにマッチする。|
| BRE: \( \)           | 【包括指定子】括弧に囲まれた範囲の文字列を、繰り返し指定子の１文字として扱わせたい場合、もしくはsed等で置換後に再利用したい文字列の範囲を指定する  |


参考
-----------------------------------

> ★これ読めばほぼ全て解決
> Qiita - どのUNIXコマンドでも使える正規表現
> http://qiita.com/richmikan@github/items/b6fb641e5b2b9af3522e

> WIKIBOOKS - Regular Expressions/POSIX Basic Regular Expressions
> https://en.wikibooks.org/wiki/Regular_Expressions/POSIX_Basic_Regular_Expressions

> 浮子屋本舗 - 正規表現講座
> http://ukiya.sakura.ne.jp/index.php?%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE%E8%AC%9B%E5%BA%A7