web-dev-qa-db-fra.com

Quel est le test le plus efficace pour savoir si un PHP chaîne se termine par une autre chaîne?

La méthode standard PHP pour vérifier si une chaîne $str se termine par une sous-chaîne $test est la suivante:

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

Est-ce le moyen le plus rapide?

113
Jason Cohen

Ce que dit Assaf est correct. Il existe une fonction intégrée dans PHP pour faire exactement cela.

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

Si $test est plus long que $str PHP donnera un avertissement, vous devez donc le vérifier en premier.

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

Cette méthode consomme un peu plus de mémoire, mais elle est plus rapide:

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

C’est mieux lorsque vous savez exactement ce que l’aiguille est, afin que vous puissiez coder en dur l’inverse. Si vous inversez l'aiguille par programmation, cela devient plus lent que la méthode précédente. 

65
jscheel
$endsWith = substr_compare( $str, $test, -strlen( $test ) ) === 0

Le décalage négatif "commence à compter à partir de la fin de la chaîne".

45
Alexander Yanovets

Voici un moyen simple de vérifier si une chaîne se termine par une autre en donnant à strpos un décalage juste à l'endroit où la chaîne doit être trouvée:

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

Je pense que cela fonctionnera dans PHP 4.

11
Patrick Smith

Cela dépend du type d'efficacité qui vous tient à coeur.

Votre version utilise plus de mémoire en raison de la copie supplémentaire résultant de l'utilisation de substr.

Une autre version pourrait rechercher dans la chaîne d'origine la dernière occurrence de la sous-chaîne sans effectuer de copie, mais serait probablement plus lente en raison de tests supplémentaires.

Le moyen le plus efficace consiste probablement à effectuer une comparaison caractère par caractère de la position -sterlen (test) jusqu'à la fin de la chaîne et à la comparer. C'est le minimum de comparaisons que vous pouvez espérer et il n'y a pratiquement pas de mémoire supplémentaire utilisée.

8
Assaf Lavie

Une autre solution consisterait à utiliser la fonction strrpos :

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

Mais ce n’est pas plus rapide.

4
Gumbo

J'espère que la réponse ci-dessous sera efficace et simple:

$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';
2
Srinivasan.S

Je ne sais pas si c'est rapide ou non, mais pour un test à un seul caractère, ces méthodes fonctionnent aussi

(array_pop(str_split($string)) === $test) ? true : false;
($string[strlen($string)-1] === $test) ? true : false;
(strrev($string)[0] === $test) ? true : false;
1
wloske

moyen le plus simple de le vérifier via une expression régulière

par exemple pour vérifier si le courrier donné est gmail:

echo (preg_match("/@gmail\.com$/","[email protected]"))?'true':'false';
0
Biskrem Muhammad

Je pense que les fonctions inverses comme strrchr () vous aideraient à faire correspondre le plus rapidement possible la fin de la chaîne.

0
tkotitan