15
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

Organization

PHPでStartsWith/EndsWith

大昔に書いて今でも多用しているPHP版startsWithendsWithを投稿しときます。
毎回strposを書くのもイケてないので、私はこんな感じで実装しています。

startsWithを書いてみる

strposをラップする形でstartsWith
function startsWith($haystack, $needle) {
    return (strpos($haystack, $needle) === 0);
}

endsWithを書いてみる

同様にEndsWithも書きたいところですが…
strrposを使わずに書いた場合。

endsWith
function endsWith($haystack, $needle) {
    return (strlen($haystack) > strlen($needle)) ? (substr($haystack, -strlen($needle)) == $needle) : false;
}

我ながらなんて分かりづらい書き方しているんだ…とちょっと暗い気持ちになりました…。
needleよりもhaystackの方が文字数が大きければ、haystackの後ろからneedleの文字数分抜き出して文字列の比較をし、一致すればTRUE、それ以外はFALSE

※個人で使っている関数はstrlenmb_strlenにしてマルチバイトにも対応するようにしています。
ですが、自分の環境でmb_strlenstrlenにしてもちゃんと動く模様…。

※追記 2016/03/02
UTF8で文字を扱う環境であればstrlenでも問題なく使えるというコメントを頂きました。

strrpos を見てみる。

PHP: strrpos

(PHP 4, PHP 5, PHP 7)
strrpos — 文字列中に、ある部分文字列が最後に現れる場所を探す

説明

strrpos
int strrpos ( string $haystack , string $needle [, int $offset = 0 ] )

文字列 haystack の中で、needle が最後に現れる位置を探します。

strrposの戻り値の値は先頭から見た位置なのでendsWithとして使うには一工夫が必要になりますね。

strrposを使って書いてみる

endsWith(strrposを使用)
function endsWith($haystack, $needle) {
  return (strrpos($haystack, $needle) === strlen($haystack) - strlen($needle));
}

さっきのsubstrを使ったやり方よりもだいぶすっきりしました。

確認用に簡単なテストをしてみる
function endsWith($haystack, $needle) {
  return (strrpos($haystack, $needle) === strlen($haystack) - strlen($needle));
}

foreach(array("e", "ge", "oge", "hoge", "hog", "hogehoge") as $needle) {
    echo endsWith("hoge", $needle) ? "TRUE" : "FALSE";
    echo "\n";
}
結果
TRUE
TRUE
TRUE
TRUE
FALSE
FALSE

想定した動きになりましたね!

試しにマルチバイト文字も入れてみる

function endsWith($haystack, $needle) {
  return (strrpos($haystack, $needle) == strlen($haystack) - strlen($needle));
}

foreach(array("e", "ge", "げge", "eげge", "geげge", "hog", "hogeげge") as $needle) {
    echo endsWith("hogeげge", $needle) ? "TRUE" : "FALSE";
    echo "\n";
}
結果
TRUE
TRUE
TRUE
TRUE
TRUE
FALSE
TRUE

なんか納得しないけど 期待した結果になりました!

マルチバイト文字関連はちょっと気になるので、後日調べて追記しますね!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
15
Help us understand the problem. What are the problem?