PHP Letztes Vorkommen eines Strings in einem String ersetzen?


Antworten:


228

Sie können diese Funktion verwenden:

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

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

    return $subject;
}

Dies kehrte immer noch wahr zurück, egal was passierte. Ändern Sie es wie folgt: if ($ pos) {$ subject = substr_replace ($ subject, $ replace, $ pos, strlen ($ search)); return $ subject; } else {return false; }
Jazzy

4
@ Jason Es kommt nicht zurück, TRUEegal was passiert . Es gibt eine Zeichenfolge zurück, egal was passiert. Wenn ein Ersatz kann nicht gemacht werden , es gibt das Original $subject, wie substr_replace und str_replacetut.
Mischa

@ Mischa Ist das in diesem Fall nicht dasselbe? Ich habe versucht, so etwas wie! Str_lreplace zu machen, aber wenn es nicht false zurückgibt, wird es als wahr angesehen, oder? Auf jeden Fall hat mir das geholfen und ich weiß es zu schätzen. Vielen Dank.
Jazzy

1
Wie kann das funktionieren? strpos — Find the position of the first occurrence of a substring in a string- bearbeiten: wow. PHP-Genies haben wirklich eine Funktion namens strposund strrpos? Danke ....
BarryBones41

1
@Barry dies ist ein Fall , in dem PHP nicht die Schuld verdienen :-) Die Namen strukturiert sind auf den Jahrzehnte alten strstr, strrstrvon der Standard - C - Bibliothek, die die gleichen Funktionen sind. (Aber haben sie haben die Namen ändern?)
alexis

30

Ein weiterer 1-Liner aber ohne 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, die akzeptierte Lösung ist ungefähr 35% schneller als diese Lösung.
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

Die coolste Lösung meiner Meinung nach und immer noch leicht zu verstehen.
Blackbam

Warum funktioniert es mit allen umgekehrten Zeichenfolgen? Gibt es einen (ich nehme an) spezifischen Leistungsgewinn bei der Verwendung von regulären Ausdrücken?
Kamafeather

Nein, es verringert tatsächlich die Leistung, aber es liegt daran, dass Sie nur das letzte Vorkommen möchten, sodass Sie die Suche auf eins beschränken und alles umkehren, wenn Sie das erste möchten, müssen Sie nichts umkehren
Tofandel

15

Die folgende ziemlich kompakte Lösung verwendet die PCRE-positive Lookahead-Behauptung , um mit dem letzten Auftreten des interessierenden Teilstrings übereinzustimmen, d. H. Einem Auftreten des Teilstrings, dem keine anderen Vorkommen desselben Teilstrings folgen. Somit ersetzt das Beispiel das last 'fox'mit 'dog'.

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

AUSGABE: 

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

5
Die Idee ist gut, aber der Code nicht. Es muss sein:$string = 'The quick brown fox, fox, fox jumps over the lazy fox!!!'; echo preg_replace('/(fox(?!.*fox))/', 'dog', $string);
Roemer

In der Tat ändert der Code, den ich gepostet habe, alle Instanzen von "fox" mit Ausnahme der letzten in "dog", aber wir wollen genau das Gegenteil. Vielen Dank für den Hinweis, dass das Ersetzen von? = Durch ?! behebt das Problem.
John Sonderson

11

Sie könnten dies tun:

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

Ergebnis ist 'Hallo John';

Grüße


4
Dies funktioniert, solange keine wiederholten Zeichen vorhanden sind. In meiner Situation streife ich die Seitenzahl vom Archivdatum ab, sodass ich "2015-12 / 2" habe und alle / und alle 2 vom Ende "2015-1" werden.
Mike

Dies funktioniert nur, wenn das zuletzt gesuchte Vorkommen das letzte Wort ist und keine zusätzlichen Zeichen danach stehen.
AwesomeGuy

Dies funktioniert nicht, weil Sie rtrimsich nicht so verhalten, wie Sie denken. Am Ende werden alle Zeichen, die in der Suchzeichenfolge vorhanden sind, in beliebiger Reihenfolge entfernt (und immer die Ersetzung angehängt), z. B. "Hallo Wort" -> "Hallo John", "Hallo Herr" -> "Hallo John", "Hallo" motor "->" Hallo motJohn "," Hallo worldy "->" Hallo worldyJohn ".
Jake

5

Dies wird auch funktionieren:

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

UPDATE Etwas prägnantere Version ( http://ideone.com/B8i4o ):

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

Mache ich es falsch Wenn ja, ignoriere mich einfach :) ||| echo str_lreplace ("x", "y", "dieses x oder dieses x"); => Ausgabe: "y" Siehe: ideone.com/UXuTo
edorian

@edorian: Ups! Entschuldigung, ich habe in Eile gepostet, dass die richtige Version hier ist: ideone.com/vR073 .
Alix Axel

5

Nur eine Codezeile (späte Antwort, aber es lohnt sich, sie hinzuzufügen):

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

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

Die Endung $ gibt das Ende der Zeichenfolge an.


5

Dies ist eine alte Frage, aber warum übersehen alle die einfachste Regexp-basierte Lösung? Normale Regexp-Quantifizierer sind gierig, Leute! Wenn Sie die letzte Instanz eines Musters finden möchten, bleiben Sie einfach .*davor. Hier ist wie:

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

Dies ersetzt die letzte Instanz von "fox" durch "DUCK", wie es sein soll, und druckt:

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

1
Vielen Dank! Die perfekte Funktion, um meinen Gesichtsausdruck zu umwickeln, um dies zu erreichen. In meinem Fall ersetze ich das letzte Komma durch ", und". Ich bin froh, dass ich in dieser Antwortliste ein bisschen nach unten gescrollt habe.
Rlhane

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

echo $string;

Abgesehen von den Fehlern im Code hat Faruk Unal die beste Antwort. Eine Funktion macht den Trick.


Sie müssen überprüfen, ob $ findChar nicht falsch ist (wie in der akzeptierten Antwort). Wenn die Zeichenfolge keine gesuchte Zeichenfolge enthält, werden Sie benachrichtigt und das erste Zeichen wird ersetzt.
zottelig

Das ist großartig, aber so wie es aussieht, kann es nur 1 Zeichen durch 1 Zeichen ersetzen.
Pete

3

Sie können strrpos () verwenden, um die letzte Übereinstimmung zu finden.

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

$string[$findChar]=".";

echo $string;

Ausgabe: picture_0007.value


2

Abkürzung für akzeptierte Antwort

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

2

Eine kurze Version:

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

0

Verwenden Sie das "$" für einen reg-Ausdruck, um mit dem Ende der Zeichenfolge übereinzustimmen

$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
Dies funktioniert nur, wenn das letzte Vorkommen am Ende der Zeichenfolge ideone.com/nbNSNq
cawecoy

1
Dies funktioniert nicht, wenn nach dem letzten 'Fuchs' andere Zeichen erscheinen.
John Sonderson

0

Für Interessierte: Ich habe eine Funktion geschrieben, die preg_match verwendet, damit Sie sie mithilfe von Regex von rechts ersetzen können.

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;
}

Oder als Kurzkombination / Implementierung beider Optionen:

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;
}

basierend auf https://stackoverflow.com/a/3835653/3017716 und https://stackoverflow.com/a/23343396/3017716

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.