以前投稿したPHP入門の記事に書いた内容と重複がありますが、この記事にはバリデーションについて初心者が初めて学習した知識を記述しています。
#バリデーション
問い合わせフォームや会員登録などの際に、各入力項目に適した内容が入力されているかどうかチェックすること
#正規表現
特定の文字列のパターンを文字や記号で表現する手法
#正規表現の使い方
■**\d**は、1つの半角数字(0123456789)を意味する「メタ文字」
例)電話番号090-0000-0000の正規表現
\d\d\d-\d\d\d\d-\d\d\d\d
■文字の個数を限定するときは、**{n,m}や{n}**というメタ文字(量指定子)を使用する
コメントを受け2020/04/11訂正
例)日本の電話番号にマッチする正規表現
国内の固定電話の番号については以下
参考:総務省 > 電気通信番号制度 > 電話番号に関するQ&A > Q2市外局番・市内局番とはどのようなものですか?
0\d{1,4}-\d{1,4}-\d{4}
■「AまたはBのいずれか1文字」を表す場合は**[AB]**と書く
※文字数制限はなく、[ABC]であれば、「AまたはBまたはCのいずれか1文字」となる。
例)英数字またはアンダースコア
[a-z0-9_]
■「〜が1文字、または無し」を表す場合は**?を使う
■「任意の1文字」を表す場合は.**を使う
■「任意の文字が1文字以上」を表す場合**+**を使う
■[任意の文字が0文字以上」を表す場合*****を使う
■「/」をエスケープする場合****を使う
■正規表現に**( )**を使うと、囲まれた部分がキャプチャされ、連番がつけられる。
■英単語を構成する文字(大文字も小文字も両方)を表す場合は**\w**を使う
■半角スペースやタブ文字、改行文字など、目に見えない「空白文字全般」を表すメタ文字**\s**
■「A以外の任意の文字」を表す場合は**[^A]**と書く
■タブ文字を表すメタ文字**\t**
■「文字列ABCまたは文字列CDF」のor条件を表す場合はABC|DEFと書く
■行頭を表すアンカー**^**
■行末を表すアンカー
コメントを受け2020/04/11追記
参考:正規表現でPHPを脆弱にする (1) 「^ と $」 - Qiita
$は正式には、検索対象の終わりあるいは終端の改行文字の前(複数行モードでは行の終わり)を言明
となっているようで、改行文字「\n」が入っている場合でもマッチするため、
単一行モード、複数行モードによって挙動が変わらない**\z**を使用するべき。
■「英単語ABCだけ」を表す場合は**\bABC\b**と書く
■**(肯定の)後読み**
abcの「直後の位置」を表す場合は**(?<=abc)**と書く
■**(肯定の)先読み**
abcの「直前の位置」を表す場合は**(?=abc)**と書く
■**(否定の)後読み**
「abc以外の文字列の直後」を表す場合は**(?<!abc)**と書く
■**(否定の)先読み**
「abc以外の文字列の直後」を表す場合は**(?!abc)**と書く
■「( )でキャプチャされた1番目の文字列」を表す場合は、\1書く
#正規表現を使ったバリデーション
■PHPの場合
if(preg_match("/チェック方法/",チェック対象の変数)){処理内容;}
■HTML5
<input type="XXX" name="XXX" pattern="チェック方法">
#正規表現の使用例(PHP)
<?php
$abc = 012;
if(preg_match("/^[0-9]+$/",$abc)){
echo '数値です';
}else{
echo '数値ではありません';
}
?>
<?php
$mail = 'yamada@gmail.com';
// コメントを受け2020/04/11訂正
if(filter_var($mail, FILTER_VALIDATE_EMAIL)){
echo '正しいメールアドレスです';
}else{
echo '正しいメールアドレスの形ではありません';
}
?>
<?php
$tel = "090-1234-5678";
if(preg_match("/^[0-9]{2,4}-[0-9]{2,4}-[0-9]{3,4}$/",$tel)){
echo '正しい電話番号です';
}else{
echo '正しい電話番号の形ではありません';
}
?>
<?php
$zip = "100-0013";
if(preg_match("/^[0-9]{3}-[0-9]{4}$/",$zip)){
echo '正しい郵便番号です';
}else{
echo '正しい郵便番号の形ではありません';
}
?>
<?php
$zip = "1000013";
if(preg_match("/^[0-9]{7}+$/",$zip)){
echo '正しい郵便番号です';
}else{
echo '正しい郵便番号の形ではありません';
}
?>
<?php
$pass = "pass1234";
if(preg_match("/^[a-zA-Z0-9]{6,8}+$/",$pass)){
echo '正しいパスワードです';
}else{
echo '正しいパスワードの形ではありません';
}
?>
<?php
$a = "あいうえお";
if(preg_match("/^[あ-んア-ケ一-龠]+$/u",$a)){
echo '全角文字です';
}else{
echo '全角文字ではありません';
}
//全角文字をUTF-8の文字コードで指定したい時は、終わりの部分を「+$/」ではなく「+$/u」にする。
?>
コメントを受け2020/04/11追記
上記だと「々」の感じにマッチしない。
参考:phpで漢字の正規表現を調べる(utf-8) - Qiita
以下でやっと日本語の漢字にマッチする正規表現のようだ。
preg_match("/([\x{3005}\x{3007}\x{303b}\x{3400}-\x{9FFF}\x{F900}-\x{FAFF}\x{20000}-\x{2FFFF}])(.*|)/u", $hoge, $matches);
<body>
<form action="XXX" method="post">
<input type="text" name="XXX"
pattern="^[a-z0-9._ %+-]+@[a-z0-9.-]+¥.[a-z]{2,3}$">
</form>
</body>
#PHPで正規表現を行うタイミング
①HTMLのフォームで入力された情報が、PHPファイルへPOST通信で引き渡される。
②POST通信で引き渡された情報をpreg_matchでチェックする。
③チェック結果が正しい場合→insert文でデータベースに格納
④チェック結果が正しくない場合→エラーメッセージ画面へリンク
#HTMLで正規表現を行うタイミング
①index.htmlのform内のpatternでチェックする。
②チェック結果が正しい場合→HTMLのフォームで入力された情報が、PHPファイルへPOST通信で引き渡される。
③チェック結果が正しくない場合→フォーム画面でエラーメッセージを表示
④insert文でデータベースに格納