Entfernen Sie eine Zeichenfolge vom Anfang einer Zeichenfolge

146

Ich habe eine Zeichenfolge, die so aussieht:

$str = "bla_string_bla_bla_bla";

Wie kann ich die erste entfernen bla_; aber nur, wenn es am Anfang der Zeichenfolge gefunden wird?

Mit str_replace()entfernt es alle bla_ .

Alex
quelle
1
Möglicherweise finden Sie s($str)->replacePrefix('_bla')hilfreiche Informationen in dieser eigenständigen Bibliothek .
Caw

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.

Fabio Mora
quelle
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);
Tatu Ulmanen
quelle
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;
}
Pavel
quelle
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);
cbrandolino
quelle
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.

Inka
quelle
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
Aleksandar Bosakov
quelle
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));
Stefan Gabos
quelle
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));
Muzaffar Mahmood
quelle
-1
<?php
$str = 'bla_string_bla_bla_bla';
echo preg_replace('/bla_/', '', $str, 1); 
?>
Bhanu Prakash Pandey
quelle
-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);
Moor
quelle
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.");
user1016724
quelle
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