Question Les fonctions startsWith () et endsWith () en PHP
Comment puis-je écrire deux fonctions qui prendraient une chaîne et retourneraient si elle commence par le caractère / la chaîne spécifié ou se termine avec elle?
Par exemple:
$str = '|apples}';
echo startsWith($str, '|'); //Returns true
echo endsWith($str, '}'); //Returns true
1215
2018-05-07 12:14
origine
Réponses:
function startsWith($haystack, $needle)
{
$length = strlen($needle);
return (substr($haystack, 0, $length) === $needle);
}
function endsWith($haystack, $needle)
{
$length = strlen($needle);
return $length === 0 ||
(substr($haystack, -$length) === $needle);
}
Utilisez ceci si vous ne voulez pas utiliser une regex.
1291
2018-05-07 12:24
Il est possible d'utiliser strrpos
et strpos
pour vérifier start-with et se termine-avec respectivement.
Notez que l'utilisation strrpos
vérifier commence avec et strpos
pour vérifier se termine avec retournera dès que possible au lieu de vérifier toute la chaîne jusqu'à la fin. En outre, cette solution ne crée pas de chaîne temporaire. Envisager d'expliquer la raison avant de downvoting. Juste parce qu'un f-wit au DWTF ne comprend pas comment cette fonction fonctionne ou pense qu'il n'y a qu'une seule solution ne signifie pas que cette réponse est fausse.
function startsWith($haystack, $needle) {
// search backwards starting from haystack length characters from the end
return $needle === ''
|| strrpos($haystack, $needle, -strlen($haystack)) !== false;
}
function endsWith($haystack, $needle) {
// search forward starting from end minus needle length characters
if ($needle === '') {
return true;
}
$diff = \strlen($haystack) - \strlen($needle);
return $diff >= 0 && strpos($haystack, $needle, $diff) !== false;
}
Tests et résultats (comparer avec ça):
startsWith('abcdef', 'ab') -> true
startsWith('abcdef', 'cd') -> false
startsWith('abcdef', 'ef') -> false
startsWith('abcdef', '') -> true
startsWith('', 'abcdef') -> false
endsWith('abcdef', 'ab') -> false
endsWith('abcdef', 'cd') -> false
endsWith('abcdef', 'ef') -> true
endsWith('abcdef', '') -> true
endsWith('', 'abcdef') -> false
Noter la strncmp
et substr_compare
les fonctions surpasseront cette fonction.
936
2018-05-06 18:22
Dernière mise à jour: 23 août 2016
Les fonctions
function substr_startswith($haystack, $needle) {
return substr($haystack, 0, strlen($needle)) === $needle;
}
function preg_match_startswith($haystack, $needle) {
return preg_match('~' . preg_quote($needle, '~') . '~A', $haystack) > 0;
}
function substr_compare_startswith($haystack, $needle) {
return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;
}
function strpos_startswith($haystack, $needle) {
return strpos($haystack, $needle) === 0;
}
function strncmp_startswith($haystack, $needle) {
return strncmp($haystack, $needle, strlen($needle)) === 0;
}
function strncmp_startswith2($haystack, $needle) {
return $haystack[0] === $needle[0]
? strncmp($haystack, $needle, strlen($needle)) === 0
: false;
}
Tests
echo 'generating tests';
for($i = 0; $i < 100000; ++$i) {
if($i % 2500 === 0) echo '.';
$test_cases[] = [
random_bytes(random_int(1, 7000)),
random_bytes(random_int(1, 3000)),
];
}
echo "done!\n";
$functions = ['substr_startswith', 'preg_match_startswith', 'substr_compare_startswith', 'strpos_startswith', 'strncmp_startswith', 'strncmp_startswith2'];
$results = [];
foreach($functions as $func) {
$start = microtime(true);
foreach($test_cases as $tc) {
$func(...$tc);
}
$results[$func] = (microtime(true) - $start) * 1000;
}
asort($results);
foreach($results as $func => $time) {
echo "$func: " . number_format($time, 1) . " ms\n";
}
Résultats (PHP 7.0.9)
(Tri le plus rapide au plus lent)
strncmp_startswith2: 40.2 ms
strncmp_startswith: 42.9 ms
substr_compare_startswith: 44.5 ms
substr_startswith: 48.4 ms
strpos_startswith: 138.7 ms
preg_match_startswith: 13,152.4 ms
Résultats (PHP 5.3.29)
(Tri le plus rapide au plus lent)
strncmp_startswith2: 477.9 ms
strpos_startswith: 522.1 ms
strncmp_startswith: 617.1 ms
substr_compare_startswith: 706.7 ms
substr_startswith: 756.8 ms
preg_match_startswith: 10,200.0 ms
startswith_benchmark.php
217
2017-08-24 00:07
Toutes les réponses à ce jour semblent faire beaucoup de travail inutile, strlen calculations
, string allocations (substr)
, etc. 'strpos'
et 'stripos'
fonctions retournent l'indice de la première occurrence de $needle
dans $haystack
:
function startsWith($haystack,$needle,$case=true)
{
if ($case)
return strpos($haystack, $needle, 0) === 0;
return stripos($haystack, $needle, 0) === 0;
}
function endsWith($haystack,$needle,$case=true)
{
$expectedPosition = strlen($haystack) - strlen($needle);
if ($case)
return strrpos($haystack, $needle, 0) === $expectedPosition;
return strripos($haystack, $needle, 0) === $expectedPosition;
}
127
2018-05-13 21:23
function startsWith($haystack, $needle, $case = true) {
if ($case) {
return (strcmp(substr($haystack, 0, strlen($needle)), $needle) === 0);
}
return (strcasecmp(substr($haystack, 0, strlen($needle)), $needle) === 0);
}
function endsWith($haystack, $needle, $case = true) {
if ($case) {
return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0);
}
return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0);
}
Crédit à:
Vérifiez si une chaîne se termine par une autre chaîne
Vérifiez si une chaîne commence par une autre chaîne
45
2018-05-07 12:15
Les fonctions regex ci-dessus, mais avec les autres tweaks également suggérés ci-dessus:
function startsWith($needle, $haystack) {
return preg_match('/^' . preg_quote($needle, '/') . '/', $haystack);
}
function endsWith($needle, $haystack) {
return preg_match('/' . preg_quote($needle, '/') . '$/', $haystack);
}
24
2018-06-19 16:11
Si la vitesse est importante pour vous, essayez ceci (je crois que c'est la méthode la plus rapide)
Fonctionne uniquement pour les chaînes et si $ haystack est seulement 1 caractère
function startsWithChar($needle, $haystack)
{
return ($needle[0] === $haystack);
}
function endsWithChar($needle, $haystack)
{
return ($needle[strlen($needle) - 1] === $haystack);
}
$str='|apples}';
echo startsWithChar($str,'|'); //Returns true
echo endsWithChar($str,'}'); //Returns true
echo startsWithChar($str,'='); //Returns false
echo endsWithChar($str,'#'); //Returns false
21
2017-12-15 08:53
Je réalise que cela a été terminé, mais vous pouvez regarder strncmp car il vous permet de mettre la longueur de la chaîne à comparer, donc:
function startsWith($haystack, $needle, $case=true) {
if ($case)
return strncasecmp($haystack, $needle, strlen($needle)) == 0;
else
return strncmp($haystack, $needle, strlen($needle)) == 0;
}
15
2017-09-17 02:50
Voici deux fonctions qui n'introduisent pas de chaîne temporaire, ce qui peut être utile lorsque les aiguilles sont substantiellement grandes:
function startsWith($haystack, $needle)
{
return strncmp($haystack, $needle, strlen($needle)) === 0;
}
function endsWith($haystack, $needle)
{
return $needle === '' || substr_compare($haystack, $needle, -strlen($needle)) === 0;
}
15
2017-08-02 07:40
Cette question a déjà de nombreuses réponses, mais dans certains cas, vous pouvez vous contenter de quelque chose de plus simple que tous.
Si la chaîne que vous recherchez est connue (codée en dur), vous pouvez utiliser des expressions régulières sans aucun guillemets, etc.
Vérifiez si une chaîne commence par 'ABC':
preg_match('/^ABC/', $myString); // "^" here means beginning of string
se termine par "ABC":
preg_match('/ABC$/', $myString); // "$" here means end of string
Dans mon cas simple, je voulais vérifier si une chaîne se termine par une barre oblique:
preg_match('/\/$/', $myPath); // slash has to be quoted
L'avantage: puisque c'est très court et simple, vous n'avez pas besoin de définir une fonction (telle que endsWith()
) Comme montré ci-dessus.
Mais encore une fois - ce n'est pas une solution pour chaque cas, juste celui-là très spécifique.
13
2018-01-06 08:59