正規表現ってなんだろう?
正規表現とは文字列を抽象的に表現する方法です。
ここに、何冊かの本の名前が書かれたテキストファイルがあるとします。この中から、あるタイトルの本を探すことを考えてみましょう。
たとえば、「Cの絵本」「CSSの絵本」というタイトルの本を探したいとします。このとき、まずは「Cの絵本」、次に「CSSの絵本」と1冊ずつ、データの最初から順番に探していくのでは面倒です。この2冊は、最後の「の絵本」が同じなので、「の絵本」で検索して、見つかったものが「C の絵本」「CSSの絵本」のどちらかであるかを判断した方が簡単そうですね。しかし、共通しているのは「の絵本」だけでしょうか?
2冊は、最初の1文字も同じ「C」です。つまり、探したいのは、最初が「C」ではじまって、その次に「SS」が続く、またはなにも文字がなくて、最後が「の絵本」で終わるタイトルの本なのです。正規表現を使うと、このようなあいまいなタイトルを表現することができます。正規表現を使ったあいまいな表現のことをパターンといいます。
正規表現には、普通の文字のほかに、メタ文字という特別な意味をもつ文字を使います。また、複数の文字をひとまとめにした、文字クラスというものもあります。
ところで、正規表現が利用出来るのは、プログラミング言語だけではありません。少し高機能なテキストエディタであれば、検索・置換機能で正規表現が使えます。多少の方言はあるかもしれませんが、あとで紹介するメタ文字のほとんどは使えると思います。
いろいろなパターンを試してみるのもよいかもしれませんね。
メタ文字
正規表現では、メタ文字という特殊な意味をもつ文字を使うことができます。
. 任意の一文字
- 0回以上の繰り返し
+ 1回以上の繰り返し
^ 先頭
$ 末尾
| 選択
( ) 正規表現のグループ
[ ] 文字クラス{n} n回の繰り返し
{n , } n回以上の繰り返し
{n , m} n回以上m回以下の繰り返し
¥ メタ文字を文字として扱う
/ パターンの最初と最後に指定
メタ文字を使った正規表現
. 任意の1文字
N . T → NOT NET N_T など
* ひとつ前の文字を0回以上繰り返す
mo* → m mo moo
+ ひとつ前の文字を1回以上繰り返す
mo+ → mo mo mo
? 1つ前の文字を0回または1回繰り返す
https? → http https
{4} ひとつ前の文字を4回繰り返す(下の例は4つの任意の文字の意味になる)
s . {4} ing → sleeping swimming shopping
{3 , 4} 1つ前の文字を3回以上4回以下繰り返す
s . {3 ,4}ing → sleeping singing smiling
^ 先頭を表す
^ap . + → apple application
$ 末尾を表す
. + e $ → miracle circle uncle
¥ メタ文字をただの文字として使う
. + ¥.txt$ → text.txt しおり.txt
複数の文字を集めたものを文字クラスと言います。文字クラスは[ ]ではさんで記述し、はさんだ文字のどれかひとつを表します。
[ 02468 ] この中のどれか一文字
文字クラスの先頭に^をつけると、文字クラスの否定を表しています
[ ^ 024 ] →0 2 4以外のどれか1文字連続した文字列は、最初と最後の文字烈を-で繋げます。
[ 0123456789 ] →[ 0-9 ]色々な正規表現
パターンマッチ
文字列がパターンと一致することを「マッチする」といいます。マッチするかどうか調べることをパターンマッチといいます。preg_match( ) (ピーレグマッチ関数)を使います。
パターンにマッチするとマッチした文字列は配列のはじめの配列に格納されます。
preg_match(“/[A-Z]{3}/” , “Let’s study PHP” , $s);
[A-Z]{3} 大文字アルファベットで3文字。パターンは/で囲みますLet’s study PHP 対象となる文字列です
$sはマッチした文字列を格納する配列です
大文字と小文字を区別しない場合は、パターンの最後に i をつけます。
preg_match(“/^[a-z]/i” , “Let’s study PHP” , $s);
この場合、先頭がアルファベットのどれか1文字というパターンです。
HTMLタグの変換
strip_tags( )関数
HTMLタグを削除したり、他の記号に置き換えたりすることができます。
$str=”<u><b>PHP</b></u>
$new_str=strip_tags($str , “<u>”);
$strが削除の対象となるコード
“<u>”が削除したくないタグです。
ブラウザ PHP → PHP
nl2br( )関数 エヌエルツービーアール
改行文字(¥r , ¥nなど)の前にHTML改行タグを挿入します。
$str=”PHP¥rSQLite¥r”;
$new_str=nl2br($str , false);
ブラウザ PHPSQLite→PHP
SQLite
htmlspecialchars( )関数
< >などをHTMLの中で使える記号に書き換えます。
$tag=”<b>¥”PHP¥”</b>;
$new_tag=htmlspecialchars($tag , ENT_NOQUOTES);
ENT_NOQUOTESは ” を置き換えしたくないときに指定します。
<b>PHP</b> → <b>”PHP”</b>
ブラウザ “PHP” →<b>”PHP”</b>
パターンのグループ
パターンの一部にマッチした文字列を参照したいときは、( )でその部分をグループ化します。( )の中のパターンマッチした文字列は、配列の2番目以降に格納されます。
$str = “I love cat & dog.”;
preg_match(“/love( . + )and( . + )¥ ./” , $str);
. + 任意の1文字が1回以上というパターンのグループです。
郵便番号や日付などでは、文字列の形式を統一したいときがあります。正規表現を使うと、文字列が特定の形式に当てはまっているかどうかを調べられます。
$strs=”171-0022″;
if (preg_match(“/^([0-9]{3})-{[0-9]{4}$/” , $strs)){
print”正しい郵便番号です”;
}else{
print”形式が正しくありません”;
}
正規表現の文字列置き換え
正規表現で検索した文字列を置き換えするには、preg_replace( )を使います。
「pen」を「pencil」に置き換えてみます。
$str=”There is no pen. I want a pencil.”;
$str=preg_replace(“/pen/” , “pencil” , $str);
しかし、pencilとpenも置き換えされ、pencilcilになってしまいます。
→There is no pencil. I want a pencilcil.
penをpen(cil)?に置き換えすると、pencilがpeencilcilと置き換えされないようにできます。
$str2=preg_replace(“/pen(cil)?/” , “pencil” , “str”);
→There is no pencil. I want a pencil.
正規表現を使わない文字列の置き換え
str_replace( )関数
$str1=”I like yoga.”
$str2=str_replace(“yoga” , “spa” , $str1);
“I like yoga.”→”I like spa.”
配列で一括置き換えすることができます。
$str=”I like yoga and hiphop.;
$sports=array(“yoga” , “hiphop”);
$beauty=array(“spa” , “sauna”);
$newstr=str_replace($sports , $beauty , $str);
正規表現の文字列分割
正規表現で表される文字列によって文字列を分割するには、preg_split( )関数を使います。
$str=”2006 12/25″;
list($year , $month , $day)=preg_sprit( ‘/[ ¥/]/’ , $str);
大文字と小文字の変更
strtolower( )関数 大文字を小文字にします
$str = “Attention!”;
$new_str=strtolower($str);
“Attentional!”→”attentional!”
strtoupper( )関数 小文字を大文字にします
$str=”Conglatulations!”;
$new_str=strtoupper($str);
“Conglatulation!”→”CONGLATULATION!”
空白の削除
文字列の前後から「半角スペース」「¥n」などの空白や改行を取り除くことができます。
trim( )関数 先頭と末尾両方の空白を取り除きます。
先頭のみはltrim( )、末尾のみはrtrim( )で取り除くことができます。
$str=” I’m fine.”
$clean=trim($str);
” I’m fine. ” → “I’m fune.”
sprintf関数 指定した書式の文字列を作成します
$vall=123.4;
$val2=sprintf(“%d , $vall);
→123
%dは整数を作成します。
$val3=sprintf(“$f”,$vall);
小数点を作成します。
→123.400000が入ります
$val4=sprintf(“$s”,$vall);
文字列を作成します。
→”123.4が入ります”
文字列の長さを取得する
mb_strlen( ) 関数 全角、半角に関わらず1文字を1として文字の長さを数えます。
$str=”PHPの絵本”;
$length=mb_strlen($str);
「6」が$lengthの中に入ります。
文字列を検索する
strpos( )関数 指定した文字を前方から探して、はじめに現れる位置を取得します。
$place=strpos(“Hello World” , “o” , 2);
文字列の2番目以降について、oを探し、それが先頭から何番目かを数えます。
Hを0番目として数えます。4が返ります。
substr( )関数 指定した位置から文字列の一部を取り出します
$str=substr(“Hello World” , 0 , 7);
文字列の0番目から7文字を取り出します。
Hを0番目として数えます。
→Hello W
が返ります。
サンプルプログラム パスワードの形式を調べる
パスワードの形式を次のように決めて、文字が形式にあっているかどうか調べます。
ソースコード1
pssword1.html
<!DOCTYPE html>
<html lang=”ja”>
<head>
<meta charset=”UTF-8″>
<title>パスワード入力場面</title>
</head>
<body>
<form action=”password2.php” method=”post”>
<p>パスワード:<input type=”password” name=”pass”
<input type=”submit” value=”送信”></p>
</form>
</body>
</html>
ソースコード2
password2.php
<DOCTYPE html>
<html lang=”ja”>
<head>
<meta charset=”UTF-8″>
</head>
<body>
<?php
$password=$_POST[“pass”];
if(preg_match(“/^[a-z][a-z0-9_]{2,7}$/i”,$password)){
print”パスワードは正し形です<br>\n”;
}else{
print”パスワードは正しい形式ではありません<br>\n”;
}
?>
</body>
</html>
実行結果
パスワードは正しい形式です
パスワードは正しい形式ではありません
サンプルプログラム 日付を別のフォーマットに変換する
与えられた文字列が日付の形式かどうかを確認して、そうであれば別のフォーマットに変換します
ソースコード
date.php
<!DOCTYPE html>
<html lang=”ja”>
<head>
<matacharser=”UTF-8″>
</head>
<body>
<?php
$olddate=”2021/10/ 1″;
if(preg_match(“/^[ 0-9]+¥/[ 0-9]+¥/[ 0-9]+$/”,$olddate)){
//日付であれば、分割して配列に格納する
list($year, $month, $day)=preg_split(“/¥//”, $olddate);
//4桁 2桁 2桁のフォーマットで表示する
$newdate=sprintf(“%04d-%02d-%02d”, $year , $month , $day);
print $newdate;
}else{
print”日付はありませんでした。<br>¥n”;
}
?>
</body>
</html>
実行結果
日付はありませんでした
サンプルプログラム 訪問回数カウンタ
クッキーとセッションについてはこちらの記事をご参照ください。
<?php
//クッキー情報を格納する
$counter=isset($_COOKIE[‘visittimes’])?$_COOKIE[‘visittimes’]:”;
//もし変数$counterがあれば値に1増やし、なければ1を代入する
if (isset($counter)){
$counter++;
}else{
$counter=1;
}
//もし変数$counterの値が3より大きければクッキーを削除する
if($counter>3){
setcookie(‘visittimes’,$counter,time()-60);
}else{
setcookie(‘visittimes’,$counter);
}
?>
<!DOCTYPE html>
<html lang=”ja”>
<head>
<meta charset=”UTF-8″>
<meta http-equiv=”X-UA-Compatible” content=”IE=edge”>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<title>Document</title>
</head>
<body>
<?php
if($counter==1){
//初めてのアクセス
print”初めまして!<br>”;
}elseif($counter==2){
print $counter . “回目の訪問ですね”;
}elseif($counter==3){
//3回目にアクセスしたときはブラウザの種類を表示する
print $counter . “回目の訪問ですね<br>”;
print”あなたのブラウザは
\””.$_SERVER[‘HTTP_USER_AGENT’].”\”
ですね。<br>”;
}else{
//4回目にアクセスしたとき
print $counter . “回目のご訪問ですね<br>”;
print”次回訪問時に訪問回数がリセットされます<br>”;
}
?>
</body>
</html>
実行結果
はじめまして
2回目のご訪問ですね