正規表現とは、ある特定の文字列ではなく、文字列の一部をパターン化して表現する手法をいいます。 正規表現の記述方法と正規表現を使用したPHP関数「preg_match 」「preg_replace」を説明します。

パターンマッチ演算子

パターンマッチ演算子として、スラッシュ ( / ) で囲んだ文字列が正規表現であるとされます。パターンマッチ演算子には、正規表現を行う際のオプションとして、いくつかの修飾子が用意されています。次のように/の次に記述され、この場合「g」(繰り返しマッチする)が修飾子となります。メタ文字は、正規表現上の特殊な意味として用いられます。

 /(.)/g
(入力文字を1文字づつマッチさせる)
パターンマッチ演算子
文字 説明
! 否定
. 任意の1文字
[ ] 括弧内のいずれかの文字
[^ ] 括弧内のいずれかの文字以外
| または
? 直前の文字の0回または1回の繰り返し
* 直前の文字の0回以上の繰り返し
+ 直前の文字の1回以上の繰り返し
{n} 直前の文字をn回繰り返し
{n,} 直前の文字をn回以上繰り返し
{n,m} 直前の文字をn回以上、m回以下繰り返し
( ) 複数の文字列をまとめた形でパターンマッチを行います。またこのパターングループでマッチした文字列は、特殊変数 ( $ + 数字 ) に、マッチした順に代入することができます。( ex. $1, $2, $3, … )
^ 行頭
$ 行末
パターンマッチ演算子の修飾子
文字 説明
g 繰り返しマッチする
i 大文字と小文字の区別をしない
o 変数展開を1度だけ行う
m 文字列を複数行として扱う
s 文字列を単一行として扱う
x 拡張正規表現を行う
メタ文字
書式 意味
\d 数値のパターンを表します
\s スペース、タブなどの空白文字のパターンを表します
\w 大文字、小文字のアルファベット、数値、アンダースコアのパターンを表します
\D 数値以外の文字のパターンを表します
\S スペース、タブなどの空白文字以外の文字のパターンを表します
\W 大文字、小文字のアルファベット、数値、アンダースコア以外の文字のパターンを表します

日本語が入った正規表現での検索/置換

preg_matchやpreg_replace を使用して、日本語が入った正規表現を使います。この場合、文字化けが起こらないように次のように処理します。

  1. 日本語エンコードを指定する
    mb_regex_encoding(‘UTF-8’); // もしくは SJIS, EUC-JP
  2. 検索する文字( $find_text )と区切り文字(/)はあらかじめエスケープしておく
    $find_text = preg_quote($find_text, ‘/’);
  3. 正規表現を使って置換を行う
    $string=preg_replace(“/($find_text)/”, “置換する文字列”,$string );

パターンの取り出し(変数的な扱い)

置換パターンを”(” “)”で囲むとマッチした場合にグループとして参照できます。グループとして定義すると元の入力を変数のように扱うことができます。参照する際は最初のグループが”$1″以降”$2″,”$3”,”$4″……となります。

例: yyyy/MM/dd を dd MM yyyy に変換します
・ 置換パターン : ([0-9]{4})/([0-9]{2})/([0-9]{2})
・ 置換文字列 : $3 $2 $1

入力 結果
2013/08/26 26 08 2013

正規表現によるマッチング – preg_match

preg_matchは、正規表現によるマッチングを行い、次のパラメータでは、pattern で指定した正規表現により subject を検索します。

int preg_match ( string $pattern, string $subject, array &$matches )
パラメータ

pattern
正規表現で指定された検索するパターン
subject
入力文字列
matches
matches を指定した場合、検索結果が代入されます。
戻り値
マッチした場合に1、マッチしなかった場合は0を返します。

その他に、preg_match_allがあります。

例1

次の例の「\w」はメタ文字で、大文字、小文字のアルファベット、数値、アンダースコアのパターンを表し、「+」が付与されているので直前の文字の1回以上の繰り返しとなりまる。「()」になっているのでグループ化され、ここの部分がarrayの[1]、[2]にそれぞれ保存され、「.*」は”何かの文字列の0回以上の繰り返し”を示します。

<?php
$str = "https://tomosoft.jp?name=tomosoft&id=30&count=100";
preg_match('/name=(\w+).*&count=(\d+)/', $str, $match);
var_dump($match);

実行すると次のように$matchに設定されます。

array(3) { [0]=> string(29) “name=tomosoft&id=30&count=100” [1]=> string(8) “tomosoft” [2]=> string(3) “100” } 

例2

次の例では、例1では数値だった引数を連想配列名になるように設定します。「name」をサブパターン名にして、(?P\w)と書けば、一致した部分が$match[‘name’]で抜き出せます。

<?php
$str = "https://tomosoft.jp?name=tomosoft&id=30&count=100";
preg_match('/name=(?P<name>\w+).*&count=(?P<count>\d+)/', $str, $match);
var_dump($match);

実行すると次のように$matchに設定されます。

array(5) { [0]=> string(29) “name=tomosoft&id=30&count=100” [“name”]=> string(8) “tomosoft” [1]=> string(8) “tomosoft” [“count”]=> string(3) “100” [2]=> string(3) “100” } 

正規表現で文字列を置換 – preg_replace

preg_replaceは、正規表現で文字列を置換し、次のパラメータでは、pattern で指定した正規表現により subject を検索します。

int preg_replace( string $pattern, string $replacement,  string $subject, int &$count )
パラメータ

pattern
正規表現で指定された検索するパターン
replacement
置換後のテキストを指定する
subject
置換前の元テキスト
count
置換を行う最大回数。
戻り値
subjectの引数が配列の場合は配列を、その他の場合は文字列を返します

「s?」は「http」と「https」に対応するためです。「[ ]」で示すいずれかの文字で、「+」(直前の文字の1回以上の繰り返し)となります。文字エンコードがUTF-8の場合、パターンマッチ演算子の修飾子に”u”を指定する必要があります。また、phpファイル自身ものコードもUTF-8にします。

<?php
/ 対象文字列
$text = 'このサイトは、https://tomosoft.jp/design/です。';
 
// パターン
$pattern = '/((https?|ftp):\/\/[-_.!~*\'()a-zA-Z0-9;\/?:@&=+$,%#]+)/u';

// 置換後の文字列
$replacement = '<a href="$1">$1</a>';
 
// 置換
$text= preg_replace($pattern,$replacement,$text);
 
// 出力
echo $text;

実行すると次のように変換されます。

このサイトは、https://tomosoft.jp/design/です。