【備忘】【PHP】文字列検索いろいろ

# はじめに
PHPでできる文字列検索まわりをまとめました。
関数にPHPの関数リファレンスのリンクを仕込んでます。
随時更新予定です。

# 目次
#### 1. 文字列検索早見表

#### 2. 使い方・基本

1. 文章中の特定文字列の出現位置を見つけたい
2. 文章中のある位置からある位置までの文字列を抽出したい
3. 文章中の特定文字列を正規表現で見つけたい

#### 3. 使い方・応用（作成中）

1. 文章中の*ある文字が属する文の先頭*を取得する
2. 文章中の*ある文字が属する文の末尾*を取得する

# 1. 文字列検索早見表
| 関数           | 説明                                 | 返り値                                                       |
| ------------ | ---------------------------------- | --------------------------------------------------------- |
| [strpos](https://www.php.net/manual/ja/function.strpos.php)       | 文字列内に特定文字列が最初に現れる場所を見つける           | 特定文字列があった場合：見つかった位置(>=0) <br> なかった場合：false                |
| [mb_strpos](https://www.php.net/manual/ja/function.mb-strpos.php)    | 文字列内に特定文字列が最初に現れる場所を見つける（マルチバイト対応） | 特定文字列があった場合：見つかった位置(>=0) <br> なかった場合：false                |
| [strrpos](https://www.php.net/manual/ja/function.strrpos.php)      | 文字列内に特定文字列が最後に現れる場所を見つける           | 特定文字列があった場合：見つかった位置(>=0) <br> なかった場合：false                |
| [mb_strrpos](https://www.php.net/manual/ja/function.mb-strrpos.php)   | 文字列内に特定文字列が最後に現れる場所を見つける（マルチバイト対応） | 特定文字列があった場合：見つかった位置(>=0) <br> なかった場合：false                |
| [substr](https://www.php.net/manual/ja/function.substr.php)       | 指定した位置から文字列を返す                     | 基本的には文字列を返す<br>（失敗した場合はfalse）                             |
| [mb_substr](https://www.php.net/manual/ja/function.mb-substr.php)    | 指定した位置から文字列を返す（マルチバイト対応）           | 文字列を返す<br>（substrでfalseの場合、mb_substrは""となる）               |
| [mb_subcut](https://www.php.net/manual/ja/function.mb-strcut.php)    | 指定した位置からバイト単位で文字列を抽出して返す         | 文字列を返す                                                    |
| [preg_match](https://www.php.net/manual/ja/function.preg-match.php)   | 指定した正規表現にマッチするかどうか判定する             | マッチした場合：1<br>マッチしなかった場合：0<br>エラーの場合：false                 |
| [preg_replace](https://www.php.net/manual/ja/function.preg-replace.php) | 指定した正規表現にマッチした文字列を置換する             | マッチした場合：置換が行われた後の文字列<br>マッチしなかった場合：置換前の文字列<br>エラーの場合：null |

# 2. 使い方・基本
## 2-1. 文章中の特定文字列の位置を見つけたい
### [strpos(文章, 検索対象文字列)](https://www.php.net/manual/ja/function.strpos.php)
**文章の始まり**から検索対象文字列が何文字目(byte)に出てくるか確認できます。
検索対象文字列が文章中に存在しない場合はfalseを返します。

```sample.php
$text = '0123456789';
$search = '5';

// 検索
$position = mb_strpos($text, $search);
echo $position; // 5
```
```sample.php
$text = '0123456789';
$search = '32';

// 検索
$position = mb_strpos($text, $search);
var_dump($position); // false
```

### [mb_strpos(文章, 検索対象文字列)](https://www.php.net/manual/ja/function.mb-strpos.php)

strpos()は検索対象文字列の位置をバイト数で返してくれますが、それだとマルチバイトの文字列の位置を正しく返してくれません。
日本語を検索したい時は基本mb_strpos()の方を使います。

```sample.php
$text = '2005年の東京優駿馬はディープインパクトだよ';
$horse = 'ディープインパクト';

// 検索
$position = mb_strpos($text, $horse);
echo $position; // 12
```

### [strrpos(文章, 検索対象文字列)](https://www.php.net/manual/ja/function.strrpos.php)
**文章の末尾**から「検索対象文字列」が何文字目(byte)に出てくるか確認できます。

```sample.php
// strrpos
$text = '98765098765';
$search = '8';

// horseが出現する位置
$position = strrpos($text, $search);
var_dump($position); // int(7)
```
### [mb_strrpos(文章, 検索対象文字列)](https://www.php.net/manual/ja/function.mb-strrpos.php)
mb_strpos()と同様に、マルチバイト文字列の正確な位置を確認したい場合はこちらを使いましょう。

```sample.php
// mb_strrpos
$text = 'ぴえんこえてぱおん';
$search = 'ん';

// 検索
$position = mb_strrpos($text, $search); // 後方から検索
var_dump($position);	// int(8)
$position = mb_strpos($text, $search); // 前方から検索
var_dump($position);	// int(2)
```

## 2-2. 文章中のある位置からある位置までの文字列を抽出したい
### [substr(文章, 取得開始位置, [切り出す長さ]](https://www.php.net/manual/ja/function.substr.php)
取得開始位置からバイト数分文字を取得します。

```sample.php
$text = '0123456789';

$str = substr($text, 5);
var_dump($str);		// string(5) "56789"
```

### [mb_substr(文章, 取得開始位置, [切り出す長さ])](https://www.php.net/manual/ja/function.mb-substr.php)
日本語を扱う場合はこちらで。「文字数」でカウントして文字を取得します。

```sample.php
$text = 'それはマジ卍。よいちょまる。我はぴえん侍でござるよ。';
$search = 'よいちょ';

// 「よいちょ」の出現位置を取得
$position = mb_strpos($text, $search);

// 「よいちょ」以降の文を取得
$str = mb_substr($text, $position);
var_dump($str);		// string(57) "よいちょまる。我はぴえん侍でござるよ。"
```

### [mb_strcut(文章, 取得開始位置, [切り出す長さ])](https://www.php.net/manual/ja/function.mb-strcut.php)
「バイト数」でカウントして文字を取得します。
全角文字と半角文字が混在しているときにバイト単位で切り出したいときはこれ。

```sample.php
$text = 'stayhomeしか勝たん';
$byte_len = strlen($text);
var_dump($byte_len);	// int(23)←バイト数

$str = mb_strcut($text, 0, 13, 'utf-8');
var_dump($str);		// string(11) "stayhomeし"

$str = mb_strcut($text, 0, 14, 'utf-8');
var_dump($str);		// string(14) "stayhomeしか"

```
- 「stayhome」は8byte
- ひらがな感じはUTF-8で3byteなので「しか勝たん」は15byte


## 2-3. 文章中の特定文字列を正規表現で見つけたい
### [preg_match(正規表現, 文章)](https://www.php.net/manual/ja/function.preg-match.php)

```sample.php
$text = 'アンバランデンデレンハンマーカンマーベレンベレンボンボロンアンベレンボンベレン';

$result = preg_match("/ハンマーカンマー/", $text, $match);
var_dump($result);
// int(1)
var_dump($match);
//array(1) {
//	[0]=>
//  string(24) "ハンマーカンマー"
//}

```
「アンバランデンデレンハンマーカンマーベレンベレンボンボロンアンベレンボンベレン」が無事「ハンマーカンマ―」であることがわかりましたが、これではpreg_matchの魅力が伝わりづらいですね。

定番ですが、文字が郵便番号かどうかをpreg_matchを使って調べていきましょう。

```sample.php
// パターンマッチする
$text = '110-1122';
$result = preg_match("/^[0-9]{3}-[0-9]{4}$/", $text);
var_dump($result); // int(1)

// パターンマッチしない
$text = '110-112a';
$result = preg_match("/^[0-9]{3}-[0-9]{4}$/", $text);
var_dump($result); // int(0)

```
上記のように、パターンマッチしない場合は返り値が0になります。

### [preg_replace(正規表現, 置換する文字, 検索対象文字列)](https://www.php.net/manual/ja/function.preg-replace.php)
```sample.php
$text = '[東京][さいたま][千葉][ハンマーカンマー][半間神間]';
$replace = '漢字やで';
$result = preg_replace("/[一-龥]+/u", $replace, $text);
var_dump($result);
// string(82) "[漢字やで][さいたま][漢字やで][ハンマーカンマー][漢字やで]"
```

「検索対象文字列」が配列だった場合、各要素に対して置換が行われます。

```sample.php
$text_array = array(
	'東京',
	'さいたま',
	'千葉',
	'ハンマーカンマ―',
	'半間神間',
);
$replace = '漢字やで';
$result = preg_replace("/[一-龥]+/u", $replace, $text_array);
var_dump($result);
// array(5) {
//  [0]=>
//  string(12) "漢字やで"
//  [1]=>
//  string(12) "さいたま"
//  [2]=>
//  string(12) "漢字やで"
//  [3]=>
//  string(24) "ハンマーカンマ―"
//  [4]=>
//  string(12) "漢字やで"
//}
```

# 終わりに
リファレンスを見ると文字列検索系の関数はたくさんありますね。
使えそうなものはこの記事に随時取り込んでいく予定です。