第12章 正規表現

正規表現の基本

正規表現は、文字列のパターンを定義するための特殊な文字列です。これを使用して、文字列内での検索、置換、抽出などを行うことができます。

例えば、ある文字列がメールアドレスの形式をしているかどうかを確認するための正規表現は以下のようになります。

$email = "example@example.com";
$pattern = "/^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/";

if (preg_match($pattern, $email)) {
    echo "メールアドレスの形式が正しいです。";
} else {
    echo "メールアドレスの形式が正しくありません。";
}


正規表現の関数

PHPでは、preg_match()preg_replace()preg_split() など、正規表現を利用するための関数がいくつかあります。これらの関数を使うことで、文字列の検索、置換、分割などを行うことができます。


基本的なメタ文字

正規表現では、特定の意味を持つメタ文字がいくつかあります。例えば.は任意の文字を、* は直前の文字が0回以上繰り返すことを表します。これらのメタ文字を理解することで、より複雑なパターンを表現することができます。

例えば、/a.b/という正規表現は 'a' と 'b' の間に任意の一文字がある文字列を表します。

$str = "aeb";
$pattern = "/a.b/";

if (preg_match($pattern, $str)) {
    echo "パターンにマッチしました。";
} else {
    echo "パターンにマッチしませんでした。";
}


量指定子

量指定子は、直前の文字またはグループの繰り返し回数を指定します。*は0回以上、+は1回以上、?は0回または1回を表します。また、{n,m}はn回以上m回以下、{n}はちょうどn回を表します。

例えば、/a{3,5}/は 'a' が3回以上5回以下繰り返す文字列を表します。

$str = "aaaa";
$pattern = "/a{3,5}/";

if (preg_match($pattern, $str)) {
    echo "パターンにマッチしました。";
} else {
    echo "パターンにマッチしませんでした。";
}


キャラクタクラス

キャラクタクラスは、特定の文字の集合を表します。例えば、[abc]は 'a'、'b'、または 'c' のいずれかを表します。

例えば、/[abc]{3}/は 'a'、'b'、'c' のいずれかが3回繰り返す文字列を表します。

$str = "abc";
$pattern = "/[abc]{3}/";

if (preg_match($pattern, $str)) {
    echo "パターンにマッチしました。";
} else {
    echo "パターンにマッチしませんでした。";
}


グループ化とキャプチャ

正規表現では、()を使って複数の文字をグループ化することができます。これにより、一部のパターンに対して量指定子を適用したり、一致した部分文字列を後から参照したりすることができます。

例えば、/(abc){3}/は 'abc' が3回繰り返す文字列を表します。

$str = "abcabcabc";
$pattern = "/(abc){3}/";

if (preg_match($pattern, $str)) {
    echo "パターンにマッチしました。";
} else {
    echo "パターンにマッチしませんでした。";
}


前方参照と後方参照

グループ化された部分に一致するテキストは、後から参照することができます。これは、パターンの一部が同じ文字列にマッチする必要がある場合に役立ちます。前方参照は\1\2のように表現します。数字は左から数えた開始括弧の番号に対応します。

$str = "apple apple";
$pattern = "/(apple) \\1/";

if (preg_match($pattern, $str)) {
    echo "パターンにマッチしました。";
} else {
    echo "パターンにマッチしませんでした。";
}


否定的先読みと肯定的先読み

先読みは、特定のパターンが後ろに続くことを確認するための方法です。肯定的先読みは(?=...)、否定的先読みは(?!...)で表します。

$str = "apple banana";
$pattern = "/apple (?=banana)/";

if (preg_match($pattern, $str)) {
    echo "パターンにマッチしました。";
} else {
    echo "パターンにマッチしませんでした。";
}


否定的後読みと肯定的後読み

後読みは、特定のパターンが前に続いていることを確認するための方法です。肯定的後読みは(?<=...)、否定的後読みは(?で表します。

$str = "apple banana";
$pattern = "/(?<=apple) banana/";

if (preg_match($pattern, $str)) {
    echo "パターンにマッチしました。";
} else {
    echo "パターンにマッチしませんでした。";
}


境界

\bは単語の境界を、\Bは非単語の境界を表します。これは、単語全体にマッチする必要がある場合に便利です。

$str = "apple";
$pattern = "/\\bapple\\b/";

if (preg_match($pattern, $str)) {
    echo "パターンにマッチしました。";
} else {
    echo "パターンにマッチしませんでした。";
}


エスケープシーケンス

エスケープシーケンスは、特殊文字をリテラルとして扱うための手段です。例えば、.をリテラルのピリオドとしてマッチさせたい場合、\. のようにエスケープします。

$str = "apple.";
$pattern = "/apple\\./";

if (preg_match($pattern, $str)) {
    echo "パターンにマッチしました。";
} else {
    echo "パターンにマッチしませんでした。";
}


練習問題1.

以下の文字列がすべて数字で構成されているかをチェックする正規表現を作成してください。

テストデータ: "12345", "123a45", "12345 ", " 12345"


練習問題2.

以下のコードを考えてください。

電子メールアドレスの正規表現を作成してください。メールアドレスの形式は「ユーザー名@ドメイン名」です。
テストデータ: "test@example.com", "test.example", "test@.com"


練習問題3.

URLの正規表現を作成してください。URLは"http"または"https"で始まり、"www"が続くこともあります。その後にはドメイン名が続きます。

テストデータ: "http://example.com", "https://www.example.com", "example.com", "www.example.com"


7