2009-03-06 8 views
105

文字列$strが部分文字列$testで終わるかどうかをテストする標準的なPHPの方法は以下の通りです:PHPの文字列が別の文字列で終わるかどうかの最も効率的なテストは何ですか?

$endsWith = substr($str, -strlen($test)) == $test 

これが最速の方法ですか?

+2

類似:http://stackoverflow.com/questions/834303/php-startswith- and-endswith-functions – trante

+0

['s($ str) - > endsWith($ test)'](https://github.com/delight-im/PHP-Str/blob/8fd0c608d5496d43adaa899642c1cce047e076dc/src/Str。 php#L117)または['s($ str) - > endsWithIgnoreCase($ test)'](https://github.com/delight-im/PHP-Str/blob/8fd0c608d5496d43adaa899642c1cce047e076dc/src/Str.php#L131) [このスタンドアロンライブラリ](https://github.com/delight-im/PHP-Str)にあるように便利です。 – caw

答えて

132

アサフは正しいと言いました。 PHPには、それを正確に行うための関数が組み込まれています。

substr_compare($str, $test, strlen($str)-strlen($test), strlen($test)) === 0; 

$testは、あなたが最初にそれをチェックする必要があるので、警告を与える長い$str PHPを超える場合。

function endswith($string, $test) { 
    $strlen = strlen($string); 
    $testlen = strlen($test); 
    if ($testlen > $strlen) return false; 
    return substr_compare($string, $test, $strlen - $testlen, $testlen) === 0; 
} 
+0

ニース。 Assafが指摘したように、in-placeを比較するほうがsubstr()よりも速いようです。 –

+2

mcrumleyの答えはクールですが、 '=='の代わりに '==='を使用する必要があります。 '==='はより厳しく、通常はあなたが望むものを行いますが、 '=='は厄介な驚きにつながります。 mcrumleyの3番目のコードスニペットは正しいですが、最初の2つは正しくありません。 substr_compare()はいくつかのエラーの場合にfalseを返します。 PHPでは、false == 0なので、コードスニペットは文字列が見つかったことを知らせます。 ===これは起こらない。 –

+0

今日私はバグに遭遇し、PHP 5.5.11以降で提供したソリューションを壊すでしょう。 https://bugs.php.net/bug.php?id=67043 – user2180613

7

あなたが気にする効率の種類によって異なります。

あなたのバージョンでは、substrを使用したことによる余分なコピーのために、より多くのメモリが使用されます。

代替バージョンでは、コピーを作成することなく部分文字列が最後に出現するように元の文字列を検索する可能性がありますが、より多くのテストのためにおそらく遅くなります。

おそらく最も効率的な方法は、文字列の終わりまで-sterlen(テスト)位置からループchar-by-charを実行して比較することです。それはあなたが望むことができる最小の比較量であり、余分なメモリはほとんど使用されません。

4

もう一つの方法は、strrpos functionを使用することです:

strrpos($str, $test) == strlen($str) - strlen($test) 

しかし、それは速くありません。

0

私は、strrchr()のような逆の関数が文字列の終わりと最も速く一致するのに役立つと考えています。

63

この方法では、ほんの少しより多くのメモリ・高価ですが、それは速いです:

stripos(strrev($haystack), $reversed_needle) === 0; 

あなたは針が正確に何を知っているとき、これは最高ですので、あなたはそれが逆にハードコードすることができます。プログラムで針を逆にすると、前の方法よりも遅くなります。

function stringEndsWith($whole, $end) 
{ 
    return (strpos($whole, $end, strlen($whole) - strlen($end)) !== false); 
} 

わかりやすい、と私は、これはPHP 4で動作すると思います:

+0

それはちょうどとても賢いです! –

+0

+1独創性のために! –

+2

-1私はこれがより速いことを真剣に疑っています。それは難しいです(クールですが、通常は役に立たない)。 haystack *が針で終わっていない場合、 'stripos'は最悪の場合に文字列全体を繰り返しますが、' substr_compare'は多くても針の長さを比較します。はい、 'substr_compare'は、干し草の長さを計算する必要がありますが、この方法では*と*を完全にコピーする必要があります。 –

7

はここで文字列が見つからすべき場所を右オフセットstrposを与えることによって、1つの文字列が別で終わるかどうかを確認する簡単な方法です。

2

私は以下の答えは効率的でも簡単であることを願っています:

$content = "The main string to search"; 
$search = "search"; 
//For compare the begining string with case insensitive. 
if(stripos($content, $search) === 0) echo 'Yes'; 
else echo 'No'; 

//For compare the begining string with case sensitive. 
if(strpos($content, $search) === 0) echo 'Yes'; 
else echo 'No'; 

//For compare the ending string with case insensitive. 
if(stripos(strrev($content), strrev($search)) === 0) echo 'Yes'; 
else echo 'No'; 

//For compare the ending string with case sensitive. 
if(strpos(strrev($content), strrev($search)) === 0) echo 'Yes'; 
else echo 'No'; 
-1

これは純粋なPHPで、外部関数を呼び出すことなく、 s、ただしstrlenを除く)。

function endsWith ($ends, $string) 
{ 
    $strLength = strlen ($string); 
    $endsLength = strlen ($ends); 
    for ($i = 0; $i < $endsLength; $i++) 
    { 
     if ($string [$strLength - $i - 1] !== $ends [$i]) 
      return false; 
    } 
    return true; 
} 
35
$endsWith = substr_compare($str, $test, -strlen($test)) === 0 

負 "の文字列の末尾からカウントを開始し、" オフセット。

+3

IMOそれは最高の提供されたソリューションの一つです –

+4

私はできるだけ受け入れられた答え – FrancescoMM

+0

+200する必要があります。ここで重要なのは、負の長さを使うと文字列の最後の部分が得られるということです。 substrに-veの長さを指定して、$ testに対して==を実行することもできます。他の答えは悪いです。 – Nick

1

は、これが高速であるかどう知っているが、あまりにも単一文字のテスト、これらの作業のためにしないでください。

(array_pop(str_split($string)) === $test) ? true : false; 
($string[strlen($string)-1] === $test) ? true : false; 
(strrev($string)[0] === $test) ? true : false; 
関連する問題