【PHP】正規表現(PCRE関数)の使い方!チェックや置換するメソッドを解説!
この記事からわかること
- 正規表現の概要とメリット
- PHPで正規表現を使うには
- できることとメソッド
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
入力値やデータが正しいものかどうかをチェックしたいときに便利なのが正規表現です。
正規表現を使うことで複雑な条件を指定でき、メールアドレスや住所、電話番号などあらゆるデータのフォーマットを固定することができます。
今回は正規表現自体の作り方とphpにおける正規表現の使い方、そしてPCRE関数についてまとめていきたいと思います。
正規表現とは?
正規表現とは特定の文字列の中に特定の検索文字列があるかないか(マッチするかしないか)を識別できる記法です。
ワイルドカード「*」と考え方は似ていますがより複雑に、より細かい識別が可能になります。@が何文字目に必ずあるとか数字を3回以上繰り返すとか言った感じですね!
正規表現で表した検索文字列のことを正規表現パターンと言います。
正規表現パターン
/^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z\-]{8,24}$/
例えばこの正規表現パターンはパスワードのフォーマットを指定していて「半角英数字(A~Z,a~z,0~9)最低1つずつ含めた8文字以上24文字以内(記号はハイフンのみ)」というのを表現しています。
正規表現した条件を対象文字列が満たしていることを「マッチした」と言います。反対に条件を満たしていないものは「マッチしていない」となります。
正規表現パターンの構文
正規表現パターンの構文としてまずは「/〜/」(スラッシュ)で囲むのが重要になります。このように囲む文字のことをデリミタと言います。PHPが<?php〜?>で囲むのと同じ感じです。
通例的には「/ (スラッシュ)」を使いますが文字自体は記号などなら使えるものもあります。
文字列のみ指定
デリミタの中に文字列をそのまま埋め込むと「*文字列*」と同義になります。
文字列が中に含まれているものをマッチさせ、離れていたり、1文字でも違うものはマッチしません。
正規表現パターン | 対象文字列 | マッチの有無 |
---|---|---|
/data/ | data | ○ |
/taba/ | database | ○ |
/banana/ | banan | ✖️ |
/apple/ | APPLE | ✖️ |
[〜](ブラケット)で囲む
[〜](ブラケット)で文字列を囲んだ場合はその中のどれかが有ればマッチしたとみなします。
また0から9のいずれかにマッチさせたい場合は[0-9]と表すことで[0123456789]と同義になります。順番があるアルファベットも同様に[A-Z]と表すことができます。
正規表現パターン | 対象文字列 | マッチの有無 |
---|---|---|
/[ABC]/ | ABC,Americaなど | ○ |
/[DEF]/ | E,Endなど | ○ |
/[0-9]/ | 今日は5日です,2000など | ○ |
特別な記号を指定
ブラケットの先頭に^
を指定すると否定の意味になり、マッチしないものを識別できます。
正規表現パターン | 対象文字列 | マッチの有無 |
---|---|---|
/[^ABC]/ | ABC,Chocolateなど | ✖️ |
/[^DEF]/ | ABC,GHIなど | ○ |
ブラケットを使わずに^
を指定すると先頭部分にマッチするかを識別できます。反対に末尾部分のみにマッチさせたい場合は$
を指定します。
正規表現パターン | 対象文字列 | マッチの有無 |
---|---|---|
/^Al/ | Almond | ○ |
/csv$/ | index.html,csvfileなど | ✖️ |
他にも特殊な記号はあるのでまとめておきます。
正規表現パターン | 役割 | 対象文字列 | マッチの有無 |
---|---|---|---|
/ht.l/ | 任意の1文字 | index.html | ○ |
/GR*N/ | 0文字以上の文字 | GRN,GReeeeNなど | ○ |
/GR+N/ | 1文字以上の文字 | GRN | ✖️ |
/l{3}/ | n文字の文字 | Hello,absoluteなど | ✖️ |
/p{2,}/ | n文字以上の文字 | Apple,Appppleなど | ○ |
/o{2,5}/ | n文字以上の文字 | coooooooool | ✖️ |
正規表現パターンで使える記号の意味
- .→任意の1文字
- [^]→否定
- ^→先頭文字を識別
- $→末尾文字を識別
- *→0文字以上の文字
- +→1文字以上の文字
- \→特殊文字をエスケープ
- {n}→n文字の文字
- {n.}→n文字以上の文字
- {m.n}→m〜n文字の文字
正規表現パターンの構文まとめ
- パターンはデリミタで囲む
- 記号で特殊なマッチを表現
- 大文字小文字は別物(同じにもできる)
- 順番があるものは「-(ハイフン)」で指定
PHPのPCRE関数
PHPではサーバー管理やweb開発に使用されるプログラミング言語Perlと同じ文法構文を用いて正規表現を扱うことができます。PHP内ではPCRE関数(Perl-compatible regular expressions)を使うことでそれを可能にしています。compatibleは「互換性」という意味の英単語です。
正規表現を英語でRegular Expressionと言います。レギュラー(正規のもの)エクスプレッション(表現)でそのままですね!
PHPでのPCRE関数は接頭辞としてpregをつけます。pcreではないので注意してください。意味はPhp REGular exceptionの頭文字でしょうか?
ここからはPHPで使える関数の中でよく使うものをまとめていきたいと思います。
preg_match関数
preg_match関数はまさしく正規表現にマッチする文字列を検索する関数です。
返り値としてマッチしていれば1,マッチしていなければ0を返します。
対象データの中にマッチする文字列があった場合にその結果を引数に指定した変数に配列形式で格納して返します。
1つのデータの中に複数のマッチする文字列があったとしても先頭にある文字列がマッチしたら後続の文字列は判断されません。
preg_match(
string $pattern, // 正規表現パターン
string $subject, // 対象文字列
array &$matches = null, //マッチした文字列を格納
int $flags = 0, //動作フラグ
int $offset = 0 //検索の開始位置
): int|false
マッチした場合は1しなかった場合は0)
動作フラグ→PREG_OFFSET_CAPTURE
このフラグを設定した場合、各マッチに対応する文字列のオフセットも(バイト単位で)返されます。 マッチした場所が先頭から何バイト目にあるかを返してくれるということです!
$data = "apple&Apple";
if(preg_match('/ppl/',$data,$res,PREG_OFFSET_CAPTURE)){
echo "マッチ<br>";
var_dump($res);
}else{
echo "マッチしない<br>";
}
// 結果:マッチ
// array(1) { [0]=> array(2) { [0]=> string(3) "ppl" [1]=> int(1) } }
preg_match_all関数
preg_match_all関数は対象データ内を全て検索しマッチする文字列を全て抜き出してくれます。
preg_match関数の全て抜き出すバージョンで引数などは変化がありません。
preg_match_all(
string $pattern,
string $subject,
array &$matches = null,
int $flags = 0,
int $offset = 0
): int|false|null
マッチしているかどうかを文字列の最後まで確認してくれて、変数に格納する配列の値もその分増えていきます。
$data = "apple&Apple";
if(preg_match_all('/ppl/',$data,$res,PREG_OFFSET_CAPTURE)){
echo "true<br>";
var_dump($res);
}else{
echo "false<br>";
}
// 結果:マッチ
// array(1) { [0]=> array(2) { [0]=> array(2) { [0]=> string(3) "ppl" [1]=> int(1) } [1]=> array(2) { [0]=> string(3) "ppl" [1]=> int(7) } } }
preg_replace関数
preg_replace関数は正規表現にマッチした文字列を置換する関数です。
preg_replace(
string|array $pattern,
string|array $replacement,
string|array $subject,
int $limit = -1, // 置換を許可する回数 -1で無制限
int &$count = null // 置換に成功した回数を格納
): string|array|null
引数の並び順が「正規表現パターン」「置換後の文字列」「対象文字列」となっていることに注意してください。
また上限を決める$limit
は制限を設けたくない場合負数を指定します。置換回数を格納できる$count
を使う場合は、先に変数に"0"を格納し、引数の順番が狂わないように明示的に$limit
を指定しなければなりません。
$data = "apple&Apple";
$replace = "banana";
$count = 0;
echo preg_replace('/apple/',$replace,$data,-1,$count);
echo "<br>置換回数は".$count;
// 結果:banana&Apple
// 置換回数は1
preg_quote関数
preg_quote関数は正規表現で特殊な意味を持つ文字(^ , * + $ など)をただの文字列としてエスケープ(クォート)させることができる関数です。
preg_quote(string $str, ?string $delimiter = null): string
この関数を使えば例えば入力値をそのまま正規表現パターンにしたい時に*を使われて全てマッチしてしまうなんてことが起きないように対処することができます。
$pattern = preg_quote("10+"); // + をエスケープできる
echo $pattern; // 結果:10\+
$data = "10+20=10";
$replace = "30-";
echo preg_replace('/'.$pattern.'/',$replace,$data);
// 結果:30-20=10
今回はPHPにおける正規表現についてまとめてみました。
正規表現が扱えることで入力値のチェックや定型的なデータの格納に便利です。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。
公式マニュアル:PHP正規表現