Rimuovere una stringa dall'inizio di una stringa


Risposte:


339

Forma semplice, senza regex:

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

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

Richiede : 0,0369 ms (0,000,036,954 secondi)

E con:

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

Richiede : 0,1749 ms (0,000,174,999 secondi) la prima corsa (compilazione) e 0,0510 ms (0,000,051,021 secondi) dopo.

Profilato sul mio server, ovviamente.


8
Non ho mai visto l'operatore ternario abusato così gravemente, un semplice if(condition) { statement }sarebbe stato molto più chiaro.
Tatu Ulmanen,

4
@salathe: accetto le critiche. È stata una curiosità personale vedere qual è stato il più veloce.
Fabio Mora,

51
@salathe, non capisco. Sono state proposte sia soluzioni idiomatiche che regex: il confronto tra i due in termini di efficienza aiuta a trovare la risposta migliore (sempre in termini di efficienza). Perché è quel male?
cbrandolino,

5
@cbrandolino, nessuno ha detto che fosse malvagio . Ho pensato che fosse del tutto irrilevante per la domanda; proprio come "ecco due soluzioni, ed ecco una foto di alcuni gattini per più voti" sarebbe.
salathe il

5
if (substr($str, 0, strlen($prefix)) == $prefix) può essere modificato per if (0 === strpos($str, $prefix))evitare allocazioni di memoria inutili mantenendo la stessa leggibilità :)
xDaizu

63

Puoi usare espressioni regolari con il simbolo del punto di inserimento ( ^) che fissa la corrispondenza all'inizio della stringa:

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

Mi chiedo se funzioni più velocemente della substr()versione ... Immagino che lo faccia e dovrebbe essere contrassegnato come risposta corretta.
Flash Thunder,

tranne che deve essere preg_quote'd
vp_arth

Penso che questo sia molto meno doloroso per gli occhi di un programmatore e più intuitivo. Anche se perde in termini di prestazioni rispetto a un'altra soluzione suggerita (di cui dubito davvero), preferirei comunque questo.
Fr0zen,

multibyteL'incubo è un altro problema con altre soluzioni mentre funziona bene se la codifica del file è corretta. Comunque, non dovrebbe essere nell'ambito di questa domanda, quindi non mi importerebbe.
Fr0zen,

Sono tornato a menzionare che questo ha un ulteriore vantaggio nel lavorare con una serie di stringhe di argomenti. substre strposnon può accettare un array. Ecco fatto, un netto miglioramento delle prestazioni se si ha a che fare con un array. Saluti!
Fr0zenFir

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

10
Non .''è necessario.
NateS,

1
Per quello che vale dal momento che ognuno sembra essere micro-ottimizzato qui, questo è costantemente il più veloce dal mio conto. 1 milione di iterazioni arrivarono a .17 sec, mentre (substr($str, 0, strlen($prefix)) == $prefix)dalla risposta accettata fu più simile a .37
billynoah

5

Qui.

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

2
Misura 0,0000459153 secondi :)
Fabio Mora il

Buona velocità, ma questo è hard-coded per dipendere dall'ago che termina con _. Esiste una versione generale?
toddmo,

0

Penso che substr_replace faccia quello che vuoi, dove puoi limitare la sostituzione a parte della tua stringa: http://nl3.php.net/manual/en/function.substr-replace.php (Questo ti permetterà di guardare solo l'inizio della stringa.)

Puoi usare il parametro count di str_replace ( http://nl3.php.net/manual/en/function.str-replace.php ), questo ti permetterà di limitare il numero di sostituzioni, partendo da sinistra, ma non imporrà che sia all'inizio.


1
substr_replacesostituirà i caratteri nell'intervallo indicato indipendentemente dal fatto che siano il prefisso che si desidera rimuovere o qualcos'altro. L'OP vuole rimuovere bla_"solo se si trova all'inizio della stringa".
Olivier "Ölbaum" Scherler

0

Buona velocità, ma questo è hard-coded per dipendere dall'ago che termina con _. Esiste una versione generale? - toddmo il 29 giugno alle 23:26

Una versione generale:

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

Alcuni parametri di riferimento:

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

Sul mio abbastanza vecchio PC di casa:

$ php bench.php

Uscite:

   strpos+strlen : 0.158388 s
         explode : 0.126772 s

0

Ecco un approccio ancora più veloce:

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

0

Questo rimuoverà la prima corrispondenza ovunque sia trovata, ovvero inizio, metà o fine.

$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 ] )

ora fa quello che vuoi.

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

7
Si prevede che str_replace()il $countparametro della funzione sia una variabile passata per riferimento per contenere il numero di sostituzioni trovate, non limitare il numero di sostituzioni.
AL il X

-6

Rimuovi www. dall'inizio della stringa, questo è il modo più semplice (ltrim)

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

8
Il secondo parametro è una mappa di caratteri da rimuovere dal lato sinistro della stringa ( php.net/manual/function.ltrim.php ). Pertanto: ltrim($a, "w.");farebbe il lavoro solo se il dominio non iniziasse con una "w". ltrim ('m.google.com', ".omg")risultati in le.com.
frammentedreality

ma risolve il problema specifico della domanda, +1
chulian

1
risolve davvero il problema specifico che ha posto per la sua risposta, non il problema della domanda. anche se andresti con ltrimesso, viene utilizzato in modo errato. il secondo parametro è un elenco di caratteri che devono essere tagliati; quindi un singolo "w."sarebbe sufficiente.
frammentedreality

Penso, IMHO, è corretto per la domanda e per il problema.
abkrim,

2
Dopo un test con diversi test cambia la mia opinione .... non lavorare per domande su qualsiasi situazione
abkrim
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.