Entfernen Sie eine Zeichenfolge vom Anfang einer Zeichenfolge


Antworten:


339

Schlichte Form ohne Regex:

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

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

Dauer : 0,0369 ms (0,000,036,954 Sekunden)

Und mit:

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

Dauert : 0,1749 ms (0,000,174,999 Sekunden) beim ersten Durchlauf (Kompilieren) und 0,0510 ms (0,000,051,021 Sekunden) danach.

Offensichtlich auf meinem Server profiliert.


8
Ich habe noch nie gesehen, dass der ternäre Operator so stark missbraucht wurde, ein einfacher if(condition) { statement }wäre so viel klarer gewesen.
Tatu Ulmanen

4
@salathe: Ich akzeptiere die Kritik. Es war eine persönliche Neugier zu sehen, was am schnellsten war.
Fabio Mora

51
@salathe, ich verstehe es nicht. Es wurden sowohl idiomatische als auch Regex-basierte Lösungen vorgeschlagen: Der Vergleich der beiden hinsichtlich der Effizienz hilft dabei, die beste (wiederum hinsichtlich der Effizienz) Antwort zu finden. Warum ist das böse?
Cbrandolino

5
@cbrandolino, niemand sagte, es sei böse . Ich dachte nur, dass es für die Frage völlig irrelevant ist; Ähnlich wie "Hier sind zwei Lösungen, und hier ist ein Bild von einigen Kätzchen für mehr Upvotes" wäre.
salathe

5
if (substr($str, 0, strlen($prefix)) == $prefix) kann geändert werden if (0 === strpos($str, $prefix)), um unnötige Speicherzuweisung bei gleicher Lesbarkeit zu vermeiden :)
xDaizu

63

Sie können reguläre Ausdrücke mit dem Caret-Symbol ( ^) verwenden, das die Übereinstimmung am Anfang der Zeichenfolge verankert:

$str = preg_replace('/^bla_/', '', $str);

Ich frage mich, ob es schneller als die substr()Version funktioniert ... Ich denke, es funktioniert und sollte als richtige Antwort markiert werden.
Flash Thunder

außer es muss preg_quote'd
vp_arth

Ich denke, das ist für die Augen eines Programmierers viel weniger schmerzhaft und intuitiver. Selbst wenn es an Leistung gegenüber einer anderen vorgeschlagenen Lösung verliert (was ich wirklich bezweifle), würde ich dies dennoch vorziehen.
Fr0zenFyr

multibyteAlbtraum ist ein weiteres Problem bei anderen Lösungen, obwohl dies gut funktioniert, wenn die Codierung der Datei korrekt ist. Wie auch immer, es sollte nicht im Rahmen dieser Frage liegen, also wäre es mir egal.
Fr0zenFyr

Kam zurück, um zu erwähnen, dass dies einen zusätzlichen Vorteil der Arbeit mit einer Reihe von Betreffzeichenfolgen hat. substrund strposkann kein Array akzeptieren. Los geht's, ein deutlicher Leistungsgewinn, wenn Sie es mit einem Array zu tun haben. Prost!
Fr0zenFyr

20
function remove_prefix($text, $prefix) {
    if(0 === strpos($text, $prefix))
        $text = substr($text, strlen($prefix)).'';
    return $text;
}

10
Das .''wird nicht benötigt.
NateS

1
Für das, was es wert ist, da jeder hier mikrooptimiert zu sein scheint, ist dieser nach meiner Zählung durchweg am schnellsten. 1 Million Iterationen gingen um 0,17 Sekunden ein, während (substr($str, 0, strlen($prefix)) == $prefix)die akzeptierte Antwort eher
0,37

5

Hier.

$array = explode("_", $string);
if($array[0] == "bla") array_shift($array);
$string = implode("_", $array);

2
Messen Sie 0,0000459153 Sekunden :)
Fabio Mora

Gute Geschwindigkeit, aber dies ist schwer zu codieren, abhängig von der Nadel, mit der endet _. Gibt es eine allgemeine Version?
Toddmo

0

Ich denke, substr_replace macht, was Sie wollen, wo Sie Ihre Ersetzung auf einen Teil Ihrer Zeichenfolge beschränken können: http://nl3.php.net/manual/en/function.substr-replace.php (Dies ermöglicht es Ihnen, nur zu betrachten der Anfang der Zeichenfolge.)

Sie können den count-Parameter von str_replace ( http://nl3.php.net/manual/en/function.str-replace.php ) verwenden. Dadurch können Sie die Anzahl der Ersetzungen von links beginnend begrenzen wird es nicht erzwingen, am Anfang zu sein.


1
substr_replaceersetzt die Zeichen im angegebenen Bereich, unabhängig davon, ob es sich um das Präfix handelt, das Sie entfernen möchten, oder um etwas anderes. Das OP möchte bla_"nur entfernen, wenn es am Anfang der Zeichenfolge gefunden wird".
Olivier 'Ölbaum' Scherler

0

Gute Geschwindigkeit, aber dies ist hartcodiert, um von der Nadel abzuhängen, die mit _ endet. Gibt es eine allgemeine Version? - Toddmo 29. Juni um 23:26 Uhr

Eine allgemeine Version:

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

Einige Benchmarks:

<?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);

Auf meinem ziemlich alten Heim-PC:

$ php bench.php

Ausgänge:

   strpos+strlen : 0.158388 s
         explode : 0.126772 s

0

Hier ist ein noch schnellerer Ansatz:

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

0

Dadurch wird die erste Übereinstimmung entfernt, wo immer sie gefunden wird, dh Start oder Mitte oder Ende.

$str = substr($str, 0, strpos($str, $prefix)).substr($str, strpos($str, $prefix)+strlen($prefix));


-6

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

Jetzt macht was du willst.

$str = "bla_string_bla_bla_bla";
str_replace("bla_","",$str,1);

7
Es wird erwartet, dass str_replace()der $countParameter der Funktion eine Variable ist, die als Referenz übergeben wird, um die Anzahl der gefundenen Ersetzungen zu enthalten, ohne die Anzahl der Ersetzungen zu begrenzen.
AL der X

-6

Entfernen Sie www. Dies ist vom Anfang der Zeichenfolge an der einfachste Weg (ltrim).

$a="www.google.com";
echo ltrim($a, "www.");

8
Der zweite Parameter ist eine Zuordnung von Zeichen, die von der linken Seite der Zeichenfolge entfernt werden sollen ( php.net/manual/function.ltrim.php ). Deshalb: ltrim($a, "w.");würde den Job nur machen, wenn die Domain nicht mit einem "w" beginnen würde. ltrim ('m.google.com', ".omg")führt zu le.com.
Fragmentierte

aber es löst das spezifische Problem der Frage, +1
chulian

1
es löst wirklich das spezifische Problem, aus dem er für seine Antwort gemacht hat - nicht das Problem der Frage. Selbst wenn Sie mitgehen würden ltrim, wird es falsch verwendet. Der zweite Parameter ist eine Liste von Zeichen, die gekürzt werden sollten. daher wäre eine einzige "w."ausreichend.
Fragmentierte

Ich denke, IMHO, es ist richtig für Fragen und für Probleme.
Abkrim

2
Nach dem Test mit mehreren Tests ändere ich meine Meinung .... arbeite nicht für Fragen in irgendwelchen Situationen
abkrim
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.