大昔に書いて今でも多用しているPHP版startsWith
とendsWith
を投稿しときます。
毎回strpos
を書くのもイケてないので、私はこんな感じで実装しています。
startsWithを書いてみる
function startsWith($haystack, $needle) {
return (strpos($haystack, $needle) === 0);
}
endsWithを書いてみる
同様にEndsWithも書きたいところですが…
strrposを使わずに書いた場合。
function endsWith($haystack, $needle) {
return (strlen($haystack) > strlen($needle)) ? (substr($haystack, -strlen($needle)) == $needle) : false;
}
我ながらなんて分かりづらい書き方しているんだ…とちょっと暗い気持ちになりました…。
needle
よりもhaystack
の方が文字数が大きければ、haystack
の後ろからneedle
の文字数分抜き出して文字列の比較をし、一致すればTRUE
、それ以外はFALSE
※個人で使っている関数はstrlen
をmb_strlen
にしてマルチバイトにも対応するようにしています。
ですが、自分の環境でmb_strlen
をstrlen
にしてもちゃんと動く模様…。
※追記 2016/03/02
UTF8で文字を扱う環境であればstrlen
でも問題なく使えるというコメントを頂きました。
strrpos を見てみる。
(PHP 4, PHP 5, PHP 7)
strrpos — 文字列中に、ある部分文字列が最後に現れる場所を探す説明
strrpos
int strrpos ( string $haystack , string $needle [, int $offset = 0 ] )
文字列 `haystack` の中で、`needle` が最後に現れる位置を探します。
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
なんか納得しないけど 期待した結果になりました!
マルチバイト文字関連はちょっと気になるので、後日調べて追記しますね!