PHPの奇妙な冒険(文字列検索的な意味で
PHPを使っていて気付いたこと。
strpos
関数というのがあります。文字列の中に特定の文字列が現れる位置を取得する関数です。この関数の戻り値は位置を示す整数値で、見つからない場合はfalse
を返します。位置は先頭を0番目とするようです。
ということは……。
if (strpos('abcde', 'a')) { // ここにある処理は行われません }
めっちゃ困りました。0
は評価するとfalse
です。
これは、正しくはこうです。
if (strpos('abcde', 'a') !== false) { // ここにある処理は行われます }
でも、できるだけfalse
に対する比較を行いたくないです。
ところで、JavaのString.indexOf
メソッドは、文字列が見つからないときは-1
を返します。
ということは……。
function str_index($string, $search, $offset = 0) { $ret = strpos($string, $search, $offset); if ($ret === false) { $ret = -1; } return $ret; } // こう書きたい if (str_index('abcde', 'a') >= 0) { // ここにある処理は行われます } // あるいは if (str_index('abcde', 'z') < 0) { // 見つからなかったときの処理 }
これなら一貫性があって好きです。
ちょっと気になって他の言語も調べてみました。
Perlのindex
関数は文字列が見つからないときは-1
を返します。Javaと同じですね。
C++のSTLにあるString.find
メソッドは、文字列が見つからないときはnpos
という定数を返します。値はstatic_cast<size_type>(-1)
であり、大抵の場合0xffffffff
だったりします。当然これは0
より大きな値ですから、0
と比較すると危ないです。
RubyのString.index
メソッドは、文字列が見つからないときはnil
を返します。PHPのnull
相当のものです。更にString.include?
メソッドというものがあって、こちらは見つかったらtrue
、見つからなければfalse
を返します。文字列が存在するかどうかの判定にはinclude?
メソッドを使いましょう、ということですね。
PythonにはString.find
とString.index
という二種類のメソッドがあるようです。find
は文字列が見つからないときに-1
を返しますが、index
はなんとValueError
という例外を投げるようです。index
メソッドは文字列が含まれない場合には呼ぶべきではない、ということかもしれません。このあたりはRubyの考えと似ている気がします。
これだけ言語ごとに仕様が違っていると面白いです。
文字列検索は非常によく使われるのですが、だからこそ気をつけないとあぶないポイントかもしれません。
スタッフブログ|2011年11月10日
NEW ENTRY
ARCHIVE
- 2021年3月
- 2021年2月
- 2021年1月
- 2020年12月
- 2020年11月
- 2020年10月
- 2020年9月
- 2020年8月
- 2020年7月
- 2020年6月
- 2020年5月
- 2020年4月
- 2020年3月
- 2020年2月
- 2020年1月
- 2019年12月
- 2019年11月
- 2019年10月
- 2019年9月
- 2019年8月
- 2019年7月
- 2019年6月
- 2019年5月
- 2019年4月
- 2019年3月
- 2019年2月
- 2019年1月
- 2018年12月
- 2018年11月
- 2018年10月
- 2018年9月
- 2018年8月
- 2018年7月
- 2018年6月
- 2018年5月
- 2018年4月
- 2018年3月
- 2018年2月
- 2018年1月
- 2017年12月
- 2017年11月
- 2017年10月
- 2017年9月
- 2017年8月
- 2017年7月
- 2017年6月
- 2017年5月
- 2017年4月
- 2017年3月
- 2017年2月
- 2016年8月
- 2016年6月
- 2016年5月
- 2016年3月
- 2016年2月
- 2016年1月
- 2015年12月
- 2015年11月
- 2015年10月
- 2015年9月
- 2015年8月
- 2015年6月
- 2015年5月
- 2015年4月
- 2013年4月
- 2013年3月
- 2013年2月
- 2013年1月
- 2012年12月
- 2012年11月
- 2012年10月
- 2012年9月
- 2012年8月
- 2012年7月
- 2012年6月
- 2012年5月
- 2012年4月
- 2012年3月
- 2012年2月
- 2012年1月
- 2011年12月
- 2011年11月
- 2011年10月
- 2011年9月
- 2011年8月
- 2011年7月
- 2011年6月
- 2011年5月
- 2011年4月
- 2011年3月
- 2011年2月
- 2011年1月
- 2010年12月
- 2010年11月
- 2010年10月
- 2010年9月
- 2010年8月
- 2010年7月
- 2010年6月
- 2010年5月
- 2010年4月
- 2010年3月
- 2010年2月
- 2010年1月
- 2009年12月
- 2009年11月
- 2009年10月
- 2009年9月
- 2009年8月