TRASH-NEWS PHPで文字列が(純粋に)数値かどうかを判別する方法

順路
  1. ホーム
  2. 2009年
  3. 11月
  4. 25日
  5. この記事 [現在地]
Search?
お知らせ
社会人近況 (2008/09/07 0:00)
配属されてからこの方、ほぼ毎日終電での帰宅が続いているうえに毎週泊まりがけの出張が入っているため、1週間に1回か2回更新できればマシといった状況です。実はまだTRASH-NEWSは概要ページもリンクコーナーもろくに作っていないような有様なんですけれども、気づけばそろそろ1周年+すでに50万ヒット。……なんだこのえもいわれぬグダグダ感は……。とりあえずヴェスペリア堪能してから考えますね。
1 2 3

PHPで文字列が(純粋に)数値かどうかを判別する方法

関連ページ
  1. PHP
  2. 自作関数
TRASH-NEWSは
いろいろと紙一重なニュースサイトです
初出時刻
2009年11月25日 00時21分 投稿
最終更新時刻
2009年11月25日 01時17分 改訂
  • この記事をはてブする
  • Yahoo!ブックマークに登録

文字列が数値かどうかを判別する方法というのは
実はPHPではちょっと面倒ではないかと思う。

PHPではその判別の方法として"is_int"と"is_numeric"の2種類がデフォルトで用意されています。

is_int : "文字列が数値かどうか"を判別する関数。ただしintではないstring、つまりGETやPOSTで与えられた文字列をぶちこむとたとえ数値のみの文字列でもFALSE。

is_numeric : "文字列が数値として利用できるか"を判別する関数。ただし1.23、-123などの小数点や負の数、果ては+0123.45e6 といった16進表記もTRUEになる。

つまりどちらも一長一短かつ足しても足りない。

PHPをやっていくなかでよくほしくなるのは、"文字列が数字だけで構成されているか(文字列が純粋に数値かどうか)"を判別する関数であり、上記の関数では目的にそぐいません。すわ正規表現の出番かとなるわけですが、でもこんな些細なことにわざわざ正規表現を使うのも重い(たぶん内部処理的に)。

これまでの日曜プログラミングでは必要になったら都度考えて個別に関数を作るなり条件分岐を作るなりで対応していたのですが、いい加減専用の自作関数を作ったほうがいいよねということで、作りました。


function Is_NumStr($String){
	if(strval($String) === strval(abs(intval($String)))){
		return TRUE;
	}else{
		return FALSE;
	}
}

var_dump(Is_NumStr('123')); ← TRUE
var_dump(Is_NumStr('0123ABC'));
var_dump(Is_NumStr('123ABC'));
var_dump(Is_NumStr('123\0ABC'));
var_dump(Is_NumStr('ABC123'));
var_dump(Is_NumStr('000123'));
var_dump(Is_NumStr('0')); ← TRUE
var_dump(Is_NumStr('-123'));
var_dump(Is_NumStr('-12.3'));
var_dump(Is_NumStr('12.3'));
var_dump(Is_NumStr('0.1'));
var_dump(Is_NumStr('1.0'));

つまり、正規表現だと以下と(ほぼ)同義。
preg_match("/^[1-9]\d*$/",$String);
純粋に狭義(だけどぱっと思い浮かぶという意味ではデファクトスタンダード)の"数値"しか認めません。

果たしてどちらが処理にもたつくのか、試していないのでわかりませんが、これで正規表現バージョンより遅かったらどうしましょうね。なんとなくabsとか足を引っ張ってそうな気がしますが。

こっちのほうが早いのでは、ほかにもっと良い方法あるよ、というご意見があれば切実にお待ちしております。

----------------------------------------

[追記(1)]
しまった、これだと引数にTRUEを指定したとき[Is_NumStr(TRUE)]にTRUEだ……あと考えてみたら0のときの返り値をTRUEにしてもいいことは何もない気がする。
よって、


function Is_NumStr($String){
	if($String && strval($String) === strval(abs(intval($String))) && !is_bool($String)){
		return TRUE;
	}else{
		return FALSE;
	}
}

やべぇ、俗っぽさがいっきにプンプンしてきたぜぇぇぇ!!

----------------------------------------

[追記(2)]
あと、
preg_match("/^[1-9]\d*$/",TRUE);
で1(TRUE)が返ってくるという現象を発見。これまで正規表現バージョン使ってなかったからいいんですが、実際使ってたらこれでマズいという状況もなくはないと思われますwww

----------------------------------------

[追記(3)]
var_dump(Is_NumStr(0123));
でOUT。

intval(0123)で83になるからですね……。16/8/2進数は今回求めたい"純粋な数値"じゃない可能性があるので排除したいところ。intval(0123,10)という具合に基数を指定しないと。
というわけで


function Is_NumStr($String){
	if($String && strval($String) === strval(abs(intval($String,10))) && !is_bool($String)){
		return TRUE;
	}else{
		return FALSE;
	}
}

……しかしながら結果はダメ。
どうもintval()では基数を強制的に設定できないようです。早い話が、intval(0123)もintval(0123,10)も83。意味が、ない!!!!!!!! ※かといってエラーが返ってくるのも微妙だけど

ほか、試行錯誤しましたが、ムリっぽいです。


function Is_NumStr($String){
	if(preg_match("/^[1-9]\d*$/",$String) && !is_bool($String)){
		return TRUE;
	}else{
		return FALSE;
	}
}

という正規表現+みたいなのが一番いいのかも……という結論に……。ただまぁ、(int) 0123みたいな引数を条件分岐に使うこともないと思いますので、追記(1)のものでも実用には耐えうる……かな? やめたほうが無難ですね……。
うーん。

----------------------------------------

[追記(4)]
うっかりしてましたが、intで0123という数値を変数に代入した時点(=引数として設定した時点)でこれはもう10進数の数値ではないので、追記(3)の正規表現バージョンでもどっちみちムリ。
やるとするなら関数の最初にis_numericで数値かどうかを確認、その後、頭の文字で基数を割り出す。10進数でなければFALSE。としなければいけません。ん、基数ってどうやって求めるんだ? base_convertをかけてみて元の数字と比較するとか? ん、できるのかな? んんん。
そこまですることかどうか、もうわからなくなってきたので、追記(1)のバージョンが使えますね良かった良かったということで良いのではないでしょうか。
3連休はずっとこんなことを考えていたので、いい加減作業に戻ります。だから遅れるんだよVer.3.0も同人部も!!

今回の教訓 : 基本を覚えてから先に進め(»PHPをいじりだした頃から今に至るまでの自分)

----------------------------------------

[追記(5)]
そしてまさかのctype_digit関数

サイト内検索
検索する
このサイトについて
  • サイト名 : TRASH-NEWS
  • 分類 : ニュースとネタのサイト
  • ジャンル : 井戸端からアレゲまで
  • もっと詳しく見る
最近の記事
05月23日の記事
  1. ボタンひと押し即生成、『サークルカットジェネレータ』公開開始
04月01日の記事
  1. あの人気シリーズを作れる? 『テイルズオヴメーカー』本日公開
03月27日の記事
  1. 現在の4月のアレ進捗度30%!!
02月21日の記事
  1. 4月のアレで使う【中二なキャラクター】イラストをご提供ください
01月24日の記事
  1. サークル名ジェネレータを作ってみた
01月11日の記事
  1. 新作(※4月のアレではない)のスクリーンショット公開
01月01日の記事
  1. コミケ77(3日目)に行ってきた
12月31日の記事
  1. コミケ77、男は黙って8:00に出発
12月24日の記事
  1. FFXIIIの検索サイトを作ってみました
12月21日の記事
  1. FFXIIIの検索サイトを作ってみている
日刊人気記事ランキング
2010年11月21日のぶん
1
もうやめて下さい!! 泣いてる子もいるんですよ!!
38
2
マリオっぽい自作のゲーム改めしょぼんのアクション公開開始
28
3
FFT-A2のクリア後レビューと感想(ネタバレなし)
17
4
テイルズオブヴェスペリアの感想 【ストーリー・キャラクター編】
14
5
サークル名ジェネレータを作ってみた
12
6
Windows XP SP3インストールで不具合が起きることが発覚
11
7
ついうっかりマリオWiiとグレイセスとFFXIIIとDQVIを予約(以下略)
11
8
○○が可愛すぎて生きるのが辛い
10
9
“マリオっぽいもの”のステージを編集するエディタが公開
9
10
3Dの初音ミクを躍らせるフリーソフトMikuMikuDanceがスゴい
9

2010年11月22日 0時更新

人気記事ランキング

カテゴリ(折畳表示)
ニュース・ネタ
サブカテゴリを開く
俺研究舎
サブカテゴリを開く
お知らせ
サブカテゴリを開く
特集・企画
サブカテゴリを開く
管理人近況
サブカテゴリを開く
カスタムアーキテクチャ
1回めのようこそ!
ゲストさん
  • 文字の大きさ : 12px
  • フォント : MS Pゴシック
  • レイアウト : 3段組
  • カスタムする
カレンダー
2009年11月
«  10月 - 12月  »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30          
管理人について
管理人 : 八満かシアン
理系になり損ねた文系人間(シアンのほう)
今頃たぶん聴いている曲
Baby Baby -Electric Lovers- by ave;new feat.佐倉紗織
月別アーカイブ
2009年
2008年
2007年
最近記事に掲載した画像
サークルカットジェネレータ、公開開始です!!
サークルカットジェネレータ、公開開始です!!
テイルズオヴメーカー偽記事の画像
テイルズオヴメーカー偽記事の画像
シガアレ作ってる、の図
シガアレ作ってる、の図
手描き初音ミク
手描き初音ミク
iPhoneっぽいUIを実際にiPhoneで表示してみて比較
iPhoneっぽいUIを実際にiPhoneで表示してみて比較
画像に関するリンク
ユーティリティ
RSSフィード
ソーシャルブックマーク
  • iGoogle
  • はてなアンテナにTRASH-NEWSを追加する TRASH-NEWSのはてなブックマーク数 この記事を含むはてなブックマーク
サイトプロフィール
Powered by
  • Movable Type 4.1 + [XHTML + CSS + JavaScript] + PHP
  • TRASH-NEWS / Hachiman_Cian 2007-
このページについて
題名
PHPで文字列が(純粋に)数値かどうかを判別する方法
内容
  • 文字列が数値かどうかを判別する方法というのは 実はPHPではちょっと面倒ではない
TRASH-NEWS ロゴ
TRASH-NEWS ロゴ
TRASH-NEWS : http://www.trash-news.net/