Supprimer une chaîne du début d'une chaîne

146

J'ai une chaîne qui ressemble à ceci:

$str = "bla_string_bla_bla_bla";

Comment puis-je supprimer le premier bla_; mais seulement s'il se trouve au début de la chaîne?

Avec str_replace(), il supprime tous bla_ les.

Alex
la source
1
Vous pourriez trouver s($str)->replacePrefix('_bla')utile, comme trouvé dans cette bibliothèque autonome .
caw

Réponses:

339

Forme simple, sans regex:

$prefix = 'bla_';
$str = 'bla_string_bla_bla_bla';

if (substr($str, 0, strlen($prefix)) == $prefix) {
    $str = substr($str, strlen($prefix));
} 

Prend: 0,0369 ms (0,000,036,954 secondes)

Et avec:

$prefix = 'bla_';
$str = 'bla_string_bla_bla_bla';
$str = preg_replace('/^' . preg_quote($prefix, '/') . '/', '', $str);

Prend: 0,1749 ms (0,000,174,999 secondes) la première exécution (compilation) et 0,0510 ms (0,000,051,021 secondes) après.

Profilé sur mon serveur, évidemment.

Fabio Mora
la source
8
Je n'ai jamais vu l'opérateur ternaire aussi maltraité, un simple if(condition) { statement }aurait été tellement plus clair.
Tatu Ulmanen
4
@salathe: J'accepte les critiques. C'était une curiosité personnelle de voir ce qui était le plus rapide.
Fabio Mora
51
@salathe, je ne comprends pas. Des solutions idiomatiques et basées sur des expressions régulières ont été proposées: comparer les deux en termes d'efficacité permet de trouver la meilleure réponse (encore une fois en termes d'efficacité). Pourquoi est-ce mal?
cbrandolino
5
@cbrandolino, personne n'a dit que c'était mal . Je pensais simplement que cela n'avait aucun rapport avec la question; un peu comme "voici deux solutions, et voici une image de quelques chatons pour plus de votes positifs" serait.
salathe
5
if (substr($str, 0, strlen($prefix)) == $prefix) peut être modifié pour if (0 === strpos($str, $prefix))éviter une allocation de mémoire inutile tout en conservant la même lisibilité :)
xDaizu
63

Vous pouvez utiliser des expressions régulières avec le symbole caret ( ^) qui ancre la correspondance au début de la chaîne:

$str = preg_replace('/^bla_/', '', $str);
Tatu Ulmanen
la source
Je me demande si cela fonctionne plus rapidement que la substr()version ... Je suppose que c'est le cas, et devrait être marqué comme une bonne réponse.
Flash Thunder
sauf qu'il doit être preg_quote'd
vp_arth
Je pense que c'est beaucoup moins douloureux aux yeux d'un programmeur et plus intuitif. Même si cela perd en performance au profit d'une autre solution suggérée (dont je doute vraiment), je préférerais toujours celle-ci.
Fr0zenFyr
multibytecauchemar est un autre problème avec d'autres solutions alors que cela fonctionne bien si l'encodage du fichier est correct. Quoi qu'il en soit, cela ne devrait pas être dans le cadre de cette question, donc je m'en fiche.
Fr0zenFyr
Je suis revenu pour mentionner que cela présente un avantage supplémentaire de travailler avec un tableau de chaînes de sujet. substret strposne peut pas accepter un tableau. Voilà, un gain de performances certain si vous avez affaire à un tableau. À votre santé!
Fr0zenFyr
20
function remove_prefix($text, $prefix) {
    if(0 === strpos($text, $prefix))
        $text = substr($text, strlen($prefix)).'';
    return $text;
}
Pavel
la source
10
Le .''n'est pas nécessaire.
NateS du
1
Pour ce que ça vaut puisque tout le monde semble micro-optimiser ici, celui-ci est toujours le plus rapide à mon avis. 1 million d'itérations sont arrivées à 0,17 s, alors que (substr($str, 0, strlen($prefix)) == $prefix)la réponse acceptée ressemblait plus à
0,37
5

Ici.

$array = explode("_", $string);
if($array[0] == "bla") array_shift($array);
$string = implode("_", $array);
cbrandolino
la source
2
Mesure 0,0000459153 secondes :)
Fabio Mora
Bonne vitesse, mais c'est codé en dur pour dépendre de l'aiguille se terminant par _. Existe-t-il une version générale?
toddmo
0

Je pense que substr_replace fait ce que vous voulez, où vous pouvez limiter votre remplacement à une partie de votre chaîne: http://nl3.php.net/manual/en/function.substr-replace.php (Cela vous permettra de ne regarder que le début de la chaîne.)

Vous pouvez utiliser le paramètre count de str_replace ( http://nl3.php.net/manual/en/function.str-replace.php ), cela vous permettra de limiter le nombre de remplacements, en commençant par la gauche, mais ne l’imposera pas au début.

Inca
la source
1
substr_replaceremplacera les caractères de la plage donnée, qu'il s'agisse du préfixe que vous souhaitez supprimer ou autre. L'OP souhaite supprimer bla_"uniquement s'il se trouve au début de la chaîne".
Olivier 'Ölbaum' Scherler
0

Bonne vitesse, mais c'est codé en dur pour dépendre de l'aiguille se terminant par _. Existe-t-il une version générale? - toddmo le 29 juin à 23:26

Une version générale:

$parts = explode($start, $full, 2);
if ($parts[0] === '') {
    $end = $parts[1];
} else {
    $fail = true;
}

Quelques repères:

<?php

$iters = 100000;
$start = "/aaaaaaa/bbbbbbbbbb";
$full = "/aaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee";
$end = '';

$fail = false;

$t0 = microtime(true);
for ($i = 0; $i < $iters; $i++) {
    if (strpos($full, $start) === 0) {
        $end = substr($full, strlen($start));
    } else {
        $fail = true;
    }
}
$t = microtime(true) - $t0;
printf("%16s : %f s\n", "strpos+strlen", $t);

$t0 = microtime(true);
for ($i = 0; $i < $iters; $i++) {
    $parts = explode($start, $full, 2);
    if ($parts[0] === '') {
        $end = $parts[1];
    } else {
        $fail = true;
    }
}
$t = microtime(true) - $t0;
printf("%16s : %f s\n", "explode", $t);

Sur mon vieux PC personnel:

$ php bench.php

Les sorties:

   strpos+strlen : 0.158388 s
         explode : 0.126772 s
Aleksandar Bosakov
la source
0

Voici une approche encore plus rapide:

// strpos is faster than an unnecessary substr() and is built just for that 
if (strpos($str, $prefix) === 0) $str = substr($str, strlen($prefix));
Stefan Gabos
la source
0

Cela supprimera la première correspondance partout où elle se trouve, c'est-à-dire le début, le milieu ou la fin.

$str = substr($str, 0, strpos($str, $prefix)).substr($str, strpos($str, $prefix)+strlen($prefix));
Muzaffar Mahmood
la source
-1
<?php
$str = 'bla_string_bla_bla_bla';
echo preg_replace('/bla_/', '', $str, 1); 
?>
Bhanu Prakash Pandey
la source
-6

str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] )

fait maintenant ce que vous voulez.

$str = "bla_string_bla_bla_bla";
str_replace("bla_","",$str,1);
Tourbière
la source
7
Le paramètre de str_replace()la fonction $countdevrait être une variable transmise par référence pour contenir le nombre de remplacements trouvés, et non pour limiter le nombre de remplacements.
AL the X
-6

Supprimez www. depuis le début de la chaîne, c'est le moyen le plus simple (ltrim)

$a="www.google.com";
echo ltrim($a, "www.");
utilisateur1016724
la source
8
Le deuxième paramètre est une carte de caractères à supprimer du côté gauche de la chaîne ( php.net/manual/function.ltrim.php ). Par conséquent: ltrim($a, "w.");ne ferait le travail que si le domaine ne commencerait pas par un "w". ltrim ('m.google.com', ".omg")se traduit par le.com.
fragmentedreality
mais cela résout le problème spécifique de la question, +1
chulian
1
cela résout vraiment le problème spécifique qu'il a fait pour sa réponse - pas le problème de la question. même si vous préférez ltrim, il n'est pas utilisé correctement. le deuxième paramètre est une liste de caractères à découper; donc un seul "w."suffirait.
fragmentedreality
Je pense, à mon humble avis, que c'est correct pour la question et pour le problème.
abkrim
2
Après le test avec plusieurs tests, changez mon opinion .... ne fonctionne pas pour question sur toutes les situations
abkrim