perl や PHP で Webアプリケーションを作る際、ユーザーがフォームに入力した値を受け取って、何らかの処理を行なう、というのは基本中の基本です。
ユーザーが入力した値をチェックして、こちらが想定したフォーマットで送られているかどうか確認し、想定外の値ならばエラーを返す、というのも基本中の基本ですね。
というわけで、そんなフォームからのユーザー入力の値のエラーチェックによく使いそうな正規表現をまとめてみました。
以下、perl の方は「$FORM{'data'}」という変数の中に、 PHP の方は「$_REQUEST['data']」という変数の中に、ユーザー入力の値が入っているとします。
半角数字のみを受け付ける場合
フォームに入力された値の中に、「半角数字以外が含まれている場合」にエラーを返すには、以下のようにします。
#-- perl の場合
if($FORM{'data'} =~ /\D/){
print qq|Error: 半角数字で入力して下さい\n|;
}
#-- PHP の場合
if(preg_match("/\D/",$_REQUEST['data'])){
print ("Error: 半角数字で入力して下さい\n");
}
ただし、上記の場合はフォーム入力が空の場合はチェックを通ってしまいますので、別途チェックが必要です。
なので以下のように、「1桁以上の半角数字のみ受け付ける」ようなチェック方法の方が良いかと思います。
#-- perl の場合
if($FORM{'data'} !~ /^\d+$/){
print qq|Error: 半角数字で入力して下さい\n|;
}
#-- PHP の場合
if(!preg_match("/^\d+$/",$_REQUEST['data'])){
print ("Error: 半角数字で入力して下さい\n");
}
「5桁の数字のみ受け付ける」という場合は、以下のようにします。
#-- perl の場合
if($FORM{'data'} !~ /^\d{5}$/){
print qq|Error: 5桁の半角数字を入力して下さい\n|;
}
#-- PHP の場合
if(!preg_match("/^\d{5}$/",$_REQUEST['data'])){
print ("Error: 5桁の半角数字を入力して下さい\n");
}
桁数を変えたければ、「\d{5}」の部分を「\d{10}」とか「\d{6}」とかにすればOK。
「5桁ぴったりではなく、5桁以内(1~5桁)の半角数字のみ受け付ける」という場合は、以下のようにします。
#-- perl の場合
if($FORM{'data'} !~ /^\d{1,5}$/){
print qq|Error: 1~5桁の半角数字を入力して下さい。\n|;
}
#-- PHP の場合
if(!preg_match("/^\d{1,5}$/",$_REQUEST['data'])){
print ("Error: 1~5桁の半角数字を入力して下さい。\n");
}
1~5桁ではなく、2~4桁にしたければ「\d{1,5}」の部分を「\d{2,4}」にすれば良いですし、0~10桁にしたければ「\d{0,10}」にすればOK。
半角数字と半角ドット「.」のみ受け付ける場合
要するに、数字だけを入力して欲しいけれど、小数もOKにしたいので、小数点「.」も許可したい、という場合ですね。
半角数字と半角ドット以外が含まれている場合にエラーを返すには、以下のようにします。
#-- perl の場合
if($FORM{'data'} =~ /[^\d\.]/){
print qq|Error: 半角数字と半角ドット「.」で入力して下さい。\n|;
}
#-- PHP の場合
if(preg_match("/[^\d\.]/",$_REQUEST['data'])){
print ("Error: 半角数字と半角ドット「.」で入力して下さい。\n");
}
しかし、これも入力が空だと通ってしまいますし、半角ドットが二つ以上あっても通ってしまいますので「小数は許可したい」というニーズを超えてしまっています。
なので「一桁以上の数値からはじまっていて、0~1個の半角ドットと半角数字だけが含まれ、最後は半角数字で終わるもののみ受け付ける」という考え方で正規表現を書くのが良いかと思います。
#-- perl の場合
if($FORM{'data'} !~ /^\d$|^\d+\.?\d+$/){
print qq|Error: 半角数字と半角ドット「.」で入力して下さい。\n|;
}
#-- PHP の場合
if(!preg_match("/^\d$|^\d+\.?\d+$/",$_REQUEST['data'])){
print ("Error: 半角数字と半角ドット「.」で入力して下さい。\n");
}
上記は、「一桁の数字か、一桁以上の数字から始まって0~1個のドットを含み一桁以上の数字で終わる」もののみマッチします。
半角英数字のみ受け付ける場合
正規表現で「半角英数字」は「\w」で表すことができます。
また、「半角英数字以外」は「\W」で表すことができます。
2010/07/16追記
flagged utf8 では、「\w」に日本語が含まれるという指摘を頂きました。
※参考リンク1
参考リンク2
なので、前述の「半角数字のみを受け付ける場合」の「\d」「\D」を「\w」「\W」に置き換えるだけで基本的には問題ないかと思います。
ただし「\w」には半角アンダーバー「_」も含まれます(逆に「\W」は正確には「半角英数字とアンダーバー以外」ですね)。
なので、半角アンダーバー「_」を除外したい場合は「\w」の代わりに「[A-Za-z0-9]」を使うのが良いかと。
また、「\W」の代わりは「[^A-Za-z0-9]」になります。
たまにあるケースで、ユーザーIDが「数桁の英字+数桁の数字」(ABC0123みたいな)で固定されているケースでは、それに応じた正規表現を書くのが良いでしょう。
例えば「3桁の英字+4桁の数字」の場合は以下のようになります。
#-- perl の場合
if($FORM{'data'} !~ /^[A-Za-z]{3}\d{4}$/){
print qq|Error: 3桁の英字+4桁の数字を入力して下さい。\n|;
}
#-- PHP の場合
if(!preg_match("/^[A-Za-z]{3}\d{4}$/",$_REQUEST['data'])){
print ("Error: 3桁の英字+4桁の数字を入力して下さい。\n");
}
英字が大文字のみで統一されている場合は「[A-Za-z]」の部分を「[A-Z]」に、小文字で統一なら「[a-z]」にしても良いですが、大文字と小文字でIDに差異がないのなら、どちらでも受け付けられる方がユーザビリティが良いでしょう。
郵便番号入力欄のエラーチェック
郵便番号は、ユーザーに入力の際にハイフンを省力してもらって、数字7桁のみ受け付けるようにするのが手っ取り早くて楽ですね。
#-- perl の場合
if($FORM{'data'} !~ /^\d{7}$/){
print qq|Error: 郵便番号を半角数字(ハイフンなし)で入力して下さい\n|;
}
#-- PHP の場合
if(!preg_match("/^\d{7}$/",$_REQUEST['data'])){
print ("Error: 郵便番号を半角数字(ハイフンなし)で入力して下さい\n");
}
ハイフンありじゃないと困る、という場合は以下のような感じになります。
#-- perl の場合
if($FORM{'data'} !~ /^\d{3}-\d{4}$/){
print qq|Error: 郵便番号を半角数字(ハイフンつき)で入力して下さい\n|;
}
#-- PHP の場合
if(!preg_match("/^\d{3}-\d{4}$/",$_REQUEST['data'])){
print ("Error: 郵便番号を半角数字(ハイフンつき)で入力して下さい\n");
}
ハイフンがあってもなくても受け付けるようにしたい、という場合は以下のような感じに。
#-- perl の場合
if($FORM{'data'} !~ /^\d{3}-?\d{4}$/){
print qq|Error: 郵便番号を半角数字で入力して下さい\n|;
}
#-- PHP の場合
if(!preg_match("/^\d{3}-?\d{4}$/",$_REQUEST['data'])){
print ("Error: 郵便番号を半角数字で入力して下さい\n");
}
ハイフンがあってもなくても受け付けるようにしておいて、後でスクリプト内でハイフンを取り除いて統一させておくのが一番良いかもですね。
電話番号入力欄のエラーチェック
電話番号も、郵便番号と同じく、ユーザーに入力の際にハイフンを省略してもらうのが楽ですよね。
国内の電話番号は、多分「0から始まる10~11桁の数字」で大丈夫だと思うので、以下のような感じ。
#-- perl の場合
if($FORM{'data'} !~ /^0\d{9,10}$/){
print qq|Error: 電話番号を半角数字(ハイフンなし)で入力して下さい\n|;
}
#-- PHP の場合
if(!preg_match("/^0\d{9,10}$/",$_REQUEST['data'])){
print ("Error: 電話番号を半角数字(ハイフンなし)で入力して下さい\n");
}
携帯電話に限定するなら「1文字目と3文字目が0で、全部で11桁の数字」で良いと思うので、以下のような感じでしょうか。
#-- perl の場合
if($FORM{'data'} !~ /^0\d0\d{8}$/){
print qq|Error: 電話番号を半角数字(ハイフンなし)で入力して下さい\n|;
}
#-- PHP の場合
if(!preg_match("/^0\d0\d{8}$/",$_REQUEST['data'])){
print ("Error: 電話番号を半角数字(ハイフンなし)で入力して下さい\n");
}
ハイフンありの場合は「市外局番2~6桁-市内局番0~4桁-4桁の数字」(これで合ってるかどうか正直自信ないです)にマッチしているかどうかチェックすれば良いと思うので、以下のような感じ。
#-- perl の場合
if($FORM{'data'} !~ /^0\d{1,5}-\d{0,4}-?\d{4}$/
|| $FORM{'data'} !~ /^.{11,13}$/){
print qq|Error: 電話番号を半角数字で入力して下さい\n|;
}
#-- PHP の場合
if(!preg_match("/^0\d{1,5}-\d{0,4}-?\d{4}$/",$_REQUEST['data'])
|| !preg_match("/^.{11,13}$/",$_REQUEST['data'])){
print ("Error: 電話番号を半角数字で入力して下さい\n");
}
「市外局番2~6桁-市内局番0~4桁-4桁の数字」のチェックだけでなく、総文字数が11~13文字であるかどうかもチェックしています。
※単純な文字数チェックは length関数とか strlen関数とか使った方が良いと思いますが、今回は正規表現の記事なので、無理矢理正規表現でやってみました(^^;
他にもまだ色々ありますが、この記事書くのに意外と時間がかかったので、続きはまた次の機会に。