PHP 正規表現 メモ

# 概要
PHPで正規表現書こうとすると、
ちょいちょい忘れているので、
preg_matchとかの使い方をメモする。

# 可視化サイト
https://regexper.com/

# 正規表現によるマッチング(preg_match)
## スタンダード
```php
preg_match($pattern, $target_str, $array_result)
```

|戻り値|
|:--|
|マッチが成功なら1<br>失敗なら0<br>エラーならFALSE|

```php:マッチ結果が入る「$array_result」
array(
  [0] => パターン全体のマッチ部分,
  [1] => 1つめのキャプチャ,
  [2] => 2つめのキャプチャ,
  ...
)
```

## マッチ位置も一緒に取得
```php
preg_match($pattern, $target_str, $array_result, PREG_OFFSET_CAPTURE)
```

```php:マッチ結果が入る「$array_result」
array(
  [0] => array(
    [0] => パターン全体のマッチ部分
    [1] => マッチングが判断された箇所の開始位置
  ),
  [1] => array(
    [0] => 1つめのキャプチャ
     [1] => マッチングが判断された箇所の開始位置
  ),
  [2] => array(
    [0] => 2つめのキャプチャ
    [1] => マッチングが判断された箇所の開始位置
  ),
    ...
)
```

# マッチする全ての文字列を取り出し(preg_match_all)
## スタンダード
```php
preg_match_all($pattern, $target_str, $array_result)
```

|戻り値|
|:--|
|マッチが成功ならマッチ回数<br>失敗なら0<br>エラーならFALSE|

```php:マッチ結果が入る「$array_result」
array(
  [0] => array(
    [0] => パターン全体のマッチで、1回目のマッチ箇所
    [1] => パターン全体のマッチで、2回目のマッチ箇所
     ...
  ),
  [1] => array(
    [0] => 1つめのキャプチャで、1回目のマッチ箇所
    [1] => 1つめのキャプチャで、2回目のマッチ箇所
    ...
  ),
  [2] => array(
    [0] => 2つめのキャプチャで、1回目のマッチ箇所
    [1] => 2つめのキャプチャで、2回目のマッチ箇所
    ...
  ),
  ...
)
```

## 結果の配列を変えた場合
```php
preg_match_all($pattern, $target_str, $array_result, PREG_SET_ORDER)
```

```php:マッチ結果が入る「$array_result」
array(
  [0] => array(
    [0] => パターン全体のマッチで、1回目のマッチ箇所
    [1] => 1つめのキャプチャで、1回目のマッチ箇所
     [2] => 2つめのキャプチャで、1回目のマッチ箇所
    ...
  ),
  [1] => array(
    [0] => パターン全体のマッチで、2回目のマッチ箇所
    [1] => 1つめのキャプチャで、2回目のマッチ箇所
    [2] => 2つめのキャプチャで、2回目のマッチ箇所
    ...
  ),
  ...
)
```

# 正規表現で置換(preg_replace)
```php
preg_replace($pattern, $replace, $str)
```

```php:例
//$strで指定した文字列に対し、$patternでキャプチャを指定し、$replaceでキャプチャの1番目を取得
preg_replace("/.*:\/\/(.*)/s", "\${1}", "http://www.google.co.jp");
```

# パターンのはなし
正規表現箇所は以下の構成で表現される。

```
"/パターン/パターン修飾子"
```

## パターン(モード)修飾子
|修飾子|説明|
|:--|:--|
|なし|文字列の1行目のみ調べる|
|i|大文字と小文字の違いを無視する|
|s|改行文字を無視し、1行とみなして調べる|
|u|対象文字列をUTF-8として扱う|
|e|置換文字列をPHPコードとして実行|

## パターン
### 先頭、末尾
|パターン|説明|
|:--|:--|
|^|後に続く文字を先頭とみなす( ^a )|
|$|前にある文字を末尾とみなす( a$ )|

### 制御
|パターン|説明|
|:--|:--|
|?|最小マッチ|

**※もうちょっと解説**

```lang:最長一致の一致例
【文字列】
<h1>タイトルタイトル</h1>

【パターン】
<.+>

【結果】
<h1>タイトルタイトル</h1>
```

```lang:最短一致の一致例
【文字列】
<h1>タイトルタイトル</h1>

【パターン】
<.+?>

【結果】
<h1>
```

```lang:追加例
【文字列】
asasasasas

【パターン】
a.*?s

【結果】
as

※「.*?」は、次のsが来るまでの最小値ということになる。
```

### 繰り返し
|パターン|説明|
|:--|:--|
|*|前の文字を0個以上繰り返し( a* )|
|+|前の文字を1個以上繰り返し( a+ )|
|?|前の文字が0個、もしくは1個( a? )|
|*?|前の文字が0個以上かつ最小回数マッチ|
|+?|前の文字が1個以上かつ最小回数マッチ|
|??|前の文字が0個、もしくは1個以上かつ最小回数マッチ|
|{x,y}|前の文字をx個～y個続き( a{1,3} )|
|{x}|前の文字がx個続き( a{3} )|
|{x,}|前の文字がx個以上続き( a{3,} )|

### 任意の文字
|パターン|説明|
|:--|:--|
|.|任意の1文字( . )|
|(hoge)|文字列単位で判別|
|(hoge|fuga)|いずれかの文字列|

### グループ
|パターン|説明|
|:--|:--|
|[abc]|括弧内の文字のいずれか1文字|
|[a-z]|括弧内の範囲指定|
|[^a-z]|括弧内の範囲指定を否定 |

### キャプチャ
|パターン|説明|
|:--|:--|
|()|括弧内のパターンを1キャプチャとみなし、<br>配列戻り値の要素1以降に格納されたりする|

### パターンの略記法
|略記述|略前|説明|
|:--|:--|:--|
|\d|[0-9]|数字|
|\D|[^0-9]|数字以外|
|\w|[a-zA-Z0-9]|単語の一部とみなされる文字|
|\W|[^a-zA-Z0-9]|単語の一部ではない文字|
|\s|[\f\n\r\t\v]|空白文字|
|\S|[^ \f\n\r\t\v]|空白文字以外|

### メタ文字
|メタ文字|説明|
|:--|:--|
|\a|アラート|
|\b|バックスペース|
|\e|エスケープ|
|\f|改ページ|
|\n|改行|
|\r|復帰|
|\t|水平タブ(通常タブ)|
|\v|垂直タブ|
|\0??|制御コード 8進数|
|\x??|制御コード 16進数|