【PHP】正規表現を読めるようになるための基礎知識と使い方

PHP

正規表現とは、文字列のペターンを表現するための方法のことです。
正規表現を使って、文字列を検索したりするときに使います。
正規表現はネットで検索すればいくらでも見本が出てくるので、それを使えばいいのですが、意味がわからないとバグの温床になるため、正規表現を読めるようになるための基礎知識部分を紹介します。

正規表現で検索する preg_match()

正規表現で検索したいとき、preg_match()を使います。
第一引数に検索したい文字列を指定し、第二引数に検索対象をとります。
そして、第三引数にはその結果が渡ってきます。preg_match("//")のように検索したい文字列をスラッシュで囲みます。

例えば下の文字列から、「r49」を検索したい場合は以下の通りです。

<?php 
$string = 'bDr8_r49vd';
if(preg_match("/r49/", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
// 検索結果です
// Array ( [0] => r49 )

上のように固定の文字列を指定して検索したいだけであれば、上のようにすることで検索できます。

任意の文字列や、より柔軟な検索をしたい場合、記号をつけて検索します。
検索のときによく使う記号は以下の通りです。

よく使う表現

  • [0-9] => 0~9まで
  • [a-z] => a~zまで
  • \w => 半角英数字またはアンダースコア
  • . => 任意の一文字
  • * => 0回以上の繰り返し
  • + => 1回以上の繰り返し
  • {n} => n回の繰り返し
  • [] => 文字クラスの作成
  • [abc] => aまたはbまたはc
  • [^abc] => aまたはbまたはc以外
  • $ => 終端一致
  • ^ => 先頭一致
  • \d => 数値
  • \ => エスケープ
  • () => 文字列の抜き出し
  • i => 大文字と小文字の区別をなくす

任意の文字列を検索できる 正規表現の\w

<?php 
$string = 'bDr8_r49vd';
if(preg_match("/\w49/", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
// 検索結果です
// Array ( [0] => r49 )

「\w」は半角の英数字か、アンダースコアにマッチした場合に検索が成功します。

大文字と小文字の区別をなくす 正規表現のi

<?php 
$string = 'bDr8_r49vd';
if(preg_match("/\w49VD/", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
  //検索結果がありませんでした

if(preg_match("/\w49VD/i", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
// 検索結果です
// Array ( [0] => r49vd )

文字クラスを絞込む正規表現の[]

<?php 
$string = 'bDr8_r49vd';

// a-pとA-Pを検索
if(preg_match("/[a-pA-P]49/", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
  //検索結果がありませんでした

// a-zとA-Zを検索
if(preg_match("/[a-zA-Z]49/", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
// 検索結果です
// Array ( [0] => r49 )

特定の検索文字列の数を指定する {n}

<?php 
// 一文字
$string = 'bDr8_r49vd';
if(preg_match("/[a-zA-Z]{1}/i", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
// 検索結果です
// Array ( [0] => b ) 


// 1文字以上4文字以下
if(preg_match("/[a-zA-Z]{1,4}/i", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
// 検索結果です
// Array ( [0] => bDr ) 4文字目は数字のためその前まで

// 1文字以上
if(preg_match("/[a-zA-Z]{1,}/i", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
// 検索結果です
// Array ( [0] => bDr ) 4文字目は数字のためその前まで

{}に数字を指定することで検索文字列の数を指定することができます。
{1}なら、一文字指定になります。
{1,4}なら、一文字以上4文字以下の文字数を指定することができます。
{1,}なら、1文字以上という意味になります。
注意点としては{1, 4}などと半角スペースをいれると検索に失敗するので半角スペースは入れないようにしましょう。

後方から終端一致や前方から先端一致で探したいとき $と^

preg_match()は基本的に前方から一致するものを探します。一致しないものが出た時点で検索が終わります。
後方から探す場合は、$を使います。

<?php 
// 後方から終端一致で検索したい
$string = 'bDr8_r49vd';
if(preg_match("/[a-zA-Z]{1,}$/i", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
// 検索結果です
// Array ( [0] => vd ) 

// 前方から先端一致で検索したい
$string = 'bDr8_r49vd';
if(preg_match("/^[a-zA-Z]{1,}/i", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
// 検索結果です
// Array ( [0] => bDr )

$は終端一致といい、後ろから一致するものを探すことができます。
逆に前方の最初の文字から一致する文字列を検索するときは、^(キャレット)を使います。
検索成功するためには、一番最初の文字は少なくとも条件に一致している必要があります。
^(キャレット)がない場合は、前方から該当の文字列を探しますので、^(キャレット)のあるなしではその点が異なります。

除外したい文字列を指定する [^abc]

除外したい文字列を指定する場合は、^(キャレット)を使います。先端一致でも使用する記号のため、場所で意味がかわる点に注意しましょう。

<?php 
// 除外したい文字列を指定する
$string = 'bDr8_r49vd';
if(preg_match("/[^a-zA-Z]{1,}/i", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
// 検索結果です
// Array ( [0] => 8_ )

^(キャレット)を先端のスラッシュの直前だと先端一致という意味になり、^(キャレット)を文字列の直前につけるとその文字列を検索から除外するという意味になります。
[^a-zA-Z]であれば、小文字のaからzと大文字のAからZに一致する文字列を除外して検索することができます。

任意の一文字を指定する .

<?php 
// 任意の一文字
$string = 'bDr8_r49vd';
if(preg_match("/.{1,}/", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
// 検索結果です
// Array ( [0] => bDr8_r49vd )
// 除外したい文字列を指定する

// 2文字以上の任意の文字列
$string = 'bDr8_r49vd';
if(preg_match("/.[a-zA-Z]{2,}/", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
// 検索結果です
// Array ( [0] => bDr )

上のように.を使うと、何にでも一致する一文字から始まる文字列を指定できます。
.と合わせてn回の繰り返しを意味する{n}を使うと、任意の2文字以上や、3文字以上といった具合に指定することができます。

htmlを検索したい [^abc]{n}と([^abc]{n})

<?php 
// htmlタグをタグを含めて検索したいとき
$string = '<h3>bDr8_r49vd</h3>';
if(preg_match("/<h3>.{3,}<\/h3>/", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
// 検索結果です
// Array ( [0] =>
// bDr8_r49vd(h3のタグを含めて検索結果として出力される)
// ) 

// htmlタグの中身だけを検索したいとき
$string = '<h3>bDr8_r49vd</h3>';
if(preg_match("/<h3>(.{3,})<\/h3>/", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
// 検索結果です
// Array ( [0] =>
// bDr8_r49vd → こちらはタグを含めた検索結果
// [1] => bDr8_r49vd ) //こちらは中身だけ

htmlのタグで検索したい場合なんかに便利です。
閉じタグのスラッシュはエスケープする必要があるので、スラッシュの前にバックスラッシュを付与します。
htmlタグの中身だけを検索したいときは上のように()でかこみます。
すると、配列の0にはhtmlタグ付きの結果が格納され、1の方にはhtmlタグの中身のみが格納されます。

print_rで配列の最後のみprint_rしたいとき

これは正規表現とは直接関係がありませんが、確認の際によく使うテクニックのため合わせて紹介します。

<?php 
// htmlタグの中身だけを検索したいとき
$string = '<h3>bDr8_r49vd</h3>';
 if(preg_match("/<h3>(.{3,})<\/h3>/", $string, $result)) { echo '検索結果です
'; print_r($result[count($result) -1]); } else { echo '検索結果がありませんでした'; } // 検索結果です // bDr8_r49vd

上のように、配列の添字に、変数の長さを取得して、そこから-1することで、必ず最後の要素を指定することができます。

0回以上の繰り返し *

<?php 
// 0回以上の繰り返し
$string = 'bDr8_r49vd';
if(preg_match("/.{0,}/", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
// 検索結果です
// Array ( [0] => bDr8_r49vd )

// 0回以上の繰り返し
$string = 'bDr8_r49vd';
if(preg_match("/.*/", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
// 検索結果です
// Array ( [0] => bDr8_r49vd )

*は0回以上の繰り返しを意味するので、{0,}と同じ意味になります。

1回以上の繰り返し +

<?php 
// 1回以上の繰り返し
$string = 'bDr8_r49vd';
if(preg_match("/.+/", $string, $result)) {
  echo '検索結果です
';
  print_r($result);
} else {
  echo '検索結果がありませんでした';
}
// 検索結果です
// Array ( [0] => bDr8_r49vd )

+で1回以上の繰り返しを意味します。

郵便番号を指定したいとき

<?php 
/**
 * 郵便番号
 * 
 * 000-0055 -> OK
 * 099-099 -> NG
 * ge3-2132 -> NG
 * 9.6-3454 -> NG
 * 634-53387 -> NG
 */
$zipcode = '000-0055';
// $zipcode = '099-099';
// $zipcode = 'ge3-2132';
// $zipcode = '9.6-3454';
// $zipcode = '634-53387';

if(preg_match("/^\d{3}-\d{4}$/", $zipcode, $result)) {
    echo '郵便番号が正しいです。';
    // print_r($result);
} else {
    echo '郵便番号が正しくありません。';
}
// ("//") 初期状態
// ("/\d{3}-\d{4}/") 3桁−4桁を指定、5桁以上あっても成功してしまう
// ("/^\d{3}-\d{4}$/") 先端一致と終端一致で3桁−4桁を指定

ポイントは、先端一致と終端一致を使うことです。
数値だけを指定しても4桁あったら検索が成功してしまうため、先端一致と終端一致を指定します。

PHP

Posted by devsakaso