PHP Sostituisci l'ultima occorrenza di una stringa in una stringa?


Risposte:


228

Puoi usare questa funzione:

function str_lreplace($search, $replace, $subject)
{
    $pos = strrpos($subject, $search);

    if($pos !== false)
    {
        $subject = substr_replace($subject, $replace, $pos, strlen($search));
    }

    return $subject;
}

Questo stava ancora tornando vero, non importa quale. Considera di modificarlo in modo che sia: if ($ pos) {$ subject = substr_replace ($ subject, $ repl, $ pos, strlen ($ search)); restituisce $ subject; } else {return false; }
Jazzy,

4
@Jason Non ritorna, TRUEqualunque cosa accada . Restituisce una stringa in ogni caso. Se la sostituzione non può essere fatta restituisce l'originale $subject, proprio come substr_replace e str_replacefare.
Mischa,

@Mischa Non è la stessa cosa in questo caso? Stavo tentando di fare qualcosa come! Str_lreplace, ma se non restituisce false, è considerato vero, giusto? Ad ogni modo, questo mi ha aiutato e lo apprezzo. Grazie.
Jazzy,

1
Come può funzionare? strpos — Find the position of the first occurrence of a substring in a string- modifica: wow. I geni Php hanno davvero creato una funzione chiamata strpose strrpos? Grazie ....
BarryBones41

1
@Barry questo è un caso in cui il PHP non merita la colpa :-) I nomi sono modellati sulle vecchie di decenni strstr, strrstrdella libreria standard C, che sono le stesse funzioni. (Ma hanno dovuto cambiare il nome?)
alexis

30

Un altro 1-liner ma senza preg:

$subject = 'bourbon, scotch, beer';
$search = ',';
$replace = ', and';

echo strrev(implode(strrev($replace), explode(strrev($search), strrev($subject), 2))); //output: bourbon, scotch, and beer

3
FWIW, la soluzione accettata è circa il 35% più veloce di questa soluzione.
JustCarty,

27
$string = 'this is my world, not my world';
$find = 'world';
$replace = 'farm';
$result = preg_replace(strrev("/$find/"),strrev($replace),strrev($string),1);
echo strrev($result); //output: this is my world, not my farm

La soluzione più interessante secondo me e comunque facile da capire.
Blackbam,

Perché funziona con tutte le stringhe invertite? C'è qualche (presumo) specifico miglioramento delle prestazioni quando si usano le espressioni regolari?
Kamafeather,

No, in realtà riduce le prestazioni, ma è perché vuoi solo l'ultima occorrenza, quindi limita la ricerca a una e annulla tutto se volessi la prima non dovresti invertire nulla
Tofandel

15

La seguente soluzione piuttosto compatta utilizza l' affermazione lookahead PCRE positiva per abbinare l'ultima occorrenza della sottostringa di interesse, ovvero un'occorrenza della sottostringa che non è seguita da altre occorrenze della stessa sottostringa. Quindi l'esempio sostituisce il last 'fox'con 'dog'.

$string = 'The quick brown fox, fox, fox jumps over the lazy fox!!!';
echo preg_replace('/(fox(?!.*fox))/', 'dog', $string);

PRODUZIONE: 

The quick brown fox, fox, fox jumps over the lazy dog!!!

5
L'idea è buona, ma il codice non lo è. Deve essere:$string = 'The quick brown fox, fox, fox jumps over the lazy fox!!!'; echo preg_replace('/(fox(?!.*fox))/', 'dog', $string);
Roemer il

In effetti, il codice che ho pubblicato modifica tutte le istanze di "fox" tranne l'ultima in "cane", ma ciò che vogliamo è esattamente il contrario. Grazie per aver sottolineato che sostituendo? = Con?! risolve il problema.
John Sonderson,

11

Potresti farlo:

$str = 'Hello world';
$str = rtrim($str, 'world') . 'John';

Il risultato è 'Hello John';

Saluti


4
Funziona finché non ci sono personaggi ripetuti. Nella mia situazione sto eliminando il numero di pagina dalla data dell'archivio, quindi ho "2015-12 / 2" e ci vuole tutto / e 2 alla fine diventando "2015-1".
Mike,

Funzionerà solo se l'ultima occorrenza cercata è l'ultima parola e non ha caratteri aggiuntivi dopo di essa.
Fantastico Acquista il

Questo non funziona perché rtrimnon si comporta nel modo in cui stai pensando. Eliminerà dalla fine tutti i caratteri presenti nella stringa di ricerca in qualsiasi ordine (e aggiungerà sempre la sostituzione), ad esempio "Ciao parola" -> "Ciao Giovanni", "Ciao signore" -> "Ciao Giovanni", "Ciao motor "->" Hello motJohn "," Hello worldy "->" Hello worldyJohn ".
Jake

5

Questo funzionerà anche:

function str_lreplace($search, $replace, $subject)
{
    return preg_replace('~(.*)' . preg_quote($search, '~') . '(.*?)~', '$1' . $replace . '$2', $subject, 1);
}

AGGIORNAMENTO Versione leggermente più concisa ( http://ideone.com/B8i4o ):

function str_lreplace($search, $replace, $subject)
{
    return preg_replace('~(.*)' . preg_quote($search, '~') . '~', '$1' . $replace, $subject, 1);
}

Sto sbagliando? Se è così, ignorami :) ||| echo str_lreplace ("x", "y", "questa x o quella x"); => Output: "y" Vedi: ideone.com/UXuTo
edorian

@edorian: Oops! Siamo spiacenti, l'ho pubblicato in fretta, la versione corretta è qui: ideone.com/vR073 .
Alix Axel,

5

Solo una riga di codice (risposta in ritardo ma vale la pena aggiungerlo):

$string = 'The quick brown fox jumps over the lazy dog';
$find_me = 'dog';

preg_replace('/'. $find_me .'$/', '', $string);

la fine $ indica la fine della stringa.


5

Questa è una domanda antica, ma perché tutti trascurano la soluzione basata su regexp più semplice? I quantificatori di regexp normali sono golosi, gente! Se vuoi trovare l'ultima istanza di un pattern, ti basta attaccarlo .*di fronte. Ecco come:

$text = "The quick brown fox, fox, fox, fox, jumps over etc.";
$fixed = preg_replace("((.*)fox)", "$1DUCK", $text);
print($fixed);

Questo sostituirà l' ultima istanza di "fox" in "DUCK", come dovrebbe, e stampa:

The quick brown fox, fox, fox, DUCK, jumps over etc.

1
Grazie! La funzione perfetta per avvolgere la mia espressione per raggiungere questo obiettivo. Nel mio caso sto sostituendo l'ultima virgola con ", e". Sono contento di averlo sceso un po 'in basso in questo elenco di risposte.
rlhane

3
$string = "picture_0007_value";
$findChar =strrpos($string,"_");
if($findChar !== FALSE) {
  $string[$findChar]=".";
}

echo $string;

A parte gli errori nel codice, Faruk Unal ha la risposta migliore. Una funzione fa il trucco.


Devi controllare, se $ findChar non è falso (allo stesso modo della risposta accettata). Se la stringa non contiene una stringa cercata, viene visualizzato un avviso e il primo carattere verrà sostituito.
Shaggy

Questo è fantastico, ma così com'è può sostituire solo 1 carattere con 1 carattere.
Pete,

3

Puoi usare strrpos () per trovare l'ultima corrispondenza.

$string = "picture_0007_value";
$findChar =strrpos($string,"_");

$string[$findChar]=".";

echo $string;

Uscita: picture_0007.value


2

Stenografia per risposta accettata

function str_lreplace($search, $replace, $subject){ 
    return is_numeric($pos=strrpos($subject,$search))?
    substr_replace($subject,$replace,$pos,strlen($search)):$subject;
}

2

Una versione corta:

$NewString = substr_replace($String,$Replacement,strrpos($String,$Replace),strlen($Replace));

0

Utilizzare "$" su un'espressione reg per abbinare la fine della stringa

$string = 'The quick brown fox jumps over the lazy fox';
echo preg_replace('/fox$/', 'dog', $string);

//output
'The quick brown fox jumps over the lazy dog'

4
funziona solo se l'ultima occorrenza è alla fine della stringa ideone.com/nbNSNq
cawecoy

1
Questo non funzionerà se compaiono altri personaggi dopo l'ultima "volpe".
John Sonderson,

0

Per gli interessati: ho scritto una funzione che utilizza preg_match in modo che tu possa sostituire dal lato destro usando regex.

function preg_rreplace($search, $replace, $subject) {
    preg_match_all($search, $subject, $matches, PREG_SET_ORDER);
    $lastMatch = end($matches);

    if ($lastMatch && false !== $pos = strrpos($subject, $lastMatchedStr = $lastMatch[0])) {
        $subject = substr_replace($subject, $replace, $pos, strlen($lastMatchedStr));
    }

    return $subject;
}

O come combinazione abbreviata / implementazione di entrambe le opzioni:

function str_rreplace($search, $replace, $subject) {
    return (false !== $pos = strrpos($subject, $search)) ?
        substr_replace($subject, $replace, $pos, strlen($search)) : $subject;
}
function preg_rreplace($search, $replace, $subject) {
    preg_match_all($search, $subject, $matches, PREG_SET_ORDER);
    return ($lastMatch = end($matches)) ? str_rreplace($lastMatch[0], $replace, $subject) : $subject;
}

basato su https://stackoverflow.com/a/3835653/3017716 e https://stackoverflow.com/a/23343396/3017716

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.