PHP Замінити останнє виникнення рядка в рядку?


Відповіді:


228

Ви можете використовувати цю функцію:

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

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

    return $subject;
}

Це все одно повертало справжнє незалежно від того. Розглянемо, як змінити його так: if ($ pos) {$ subject = substr_replace ($ subject, $ substitu, $ pos, strlen ($ search)); повернути $ предмет; } else {return false; }
— Джазі

4
@Jason Це не повертається TRUEнезалежно від того. Він повертає рядок незалежно від того. Якщо заміну неможливо зробити, він повертає оригінал $subject, як substr_replace і str_replaceробити.
— Mischa

@Mischa Це не те саме в цьому випадку? Я намагався зробити щось на кшталт! Str_lreplace, але якщо воно не повертає помилку, це вважається правдою, правда? Так чи інакше, це мені допомогло, і я ціную це. Дякую.
— Джазі

1
Як це може працювати? strpos — Find the position of the first occurrence of a substring in a string- редагувати: вау. Php генії дійсно зробили функцію, яку називали strposі strrpos? Дякую ....
— BarryBones41

1
@Barry це один випадок , коли PHP не заслуговує провину :-) Імена візерункової на багато десятиліть strstr, strrstrз стандартної бібліотеки C, які одні і ті ж функції. (Але чи мали вони змінити ім’я?)
— alexis

30

Ще один 1-лайнер, але без попереднього перегляду:

$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, прийняте рішення приблизно на 35% швидше, ніж це рішення.
— 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

Найкрутіше рішення, на мій погляд, і все ще легко зрозуміти.
— Blackbam

Чому це працює з усіма перетвореними рядками? Чи є певний (припускаю) певний приріст продуктивності при використанні регулярних виразів?
— Камафезер

Ні, це насправді знижує продуктивність, але це тому, що ви хочете лише останнього явища, щоб ви обмежили пошук одним і скасували все, якщо хотіли б першого, вам не доведеться нічого перевертати
— Tofandel

15

Наведене нижче досить компактне рішення використовує позитивне твердження PCRE для визначення відповідності останнього виникнення цікавої підрядки, тобто виникнення підрядки, за яким не супроводжуються будь-які інші події тієї ж підрядки. Таким чином, приклад замінює last 'fox'з 'dog'.

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

ВИХІД: 

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

5
Ідея хороша, але код - ні. Це повинно бути:$string = 'The quick brown fox, fox, fox jumps over the lazy fox!!!'; echo preg_replace('/(fox(?!.*fox))/', 'dog', $string);
— Roemer

Дійсно, код, який я опублікував, змінює всі екземпляри "лисиці", окрім останнього, на "собаку", але те, що ми хочемо, якраз навпаки. Дякую, що вказали, що замінити? = На ?! виправляє проблему.
— Джон Сондерсон

11

Ви можете це зробити:

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

Результат - «Привіт Джон»;

З повагою


4
Це працює до тих пір, поки не буде повторених символів. У моїй ситуації я знімаю номер сторінки за датою архіву, тому у мене є "2015-12 / 2", і це означає, що всі / і всі 2 закінчуються, стаючи "2015-1".
— Майк

Це буде працювати лише в тому випадку, якщо останнє пошукове явище є останнім словом і не має додаткових символів після нього.
— AwesomeGuy

Це не працює, оскільки rtrimне веде себе так, як ти думаєш. З кінця буде викреслено будь-які символи, які існують у рядку пошуку в будь-якому порядку (і завжди додавати заміну), наприклад "Привіт слово" -> "Привіт Джон", "Привіт лорд" -> "Привіт Джон", "Привіт мотор "->" Привіт motJohn "," Привіт, світлий "->" Привіт worldyJohn ".
— Джейк

5

Це також буде працювати:

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

ОНОВЛЕННЯ Трохи більш стисла версія ( http://ideone.com/B8i4o ):

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

Я роблю це неправильно? Якщо так, просто ігноруйте мене :) ||| echo str_lreplace ("х", "у", "цей х чи той х"); => Вихід: "y" Див.: Ideone.com/UXuTo
— edorian

@edorian: На жаль! Вибачте, я поспішив, що поспішаючи, тут знайдеться правильна версія: ideone.com/vR073 .
— Алікс Аксель

5

Лише один рядок коду (пізня відповідь, але його варто додати):

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

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

закінчення $ вказує кінець рядка.


5

Це давнє запитання, але чому всі не помічають найпростішого рішення, заснованого на регулярній основі? Нормальні кількісні показники зворотного рівня, люди! Якщо ви хочете знайти останній екземпляр візерунка, просто дотримуйтесь .*його. Ось як:

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

Це замінить останній екземпляр "fox" на "DUCK", як це належить, і надрукує:

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

1
Дякую! Ідеальна функція обернутись моїм виразом, щоб досягти цього. У моєму випадку я замінюю останню кому на ",". Радий, що я трохи прокрутився в цьому списку відповідей.
— rlhane

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

echo $string;

Крім помилок у коді, Фарук Унал має найкращого шанувальника. Одна функція виконує трюк.


Вам потрібно перевірити, чи $ findChar неправдивий (так само, як у прийнятій відповіді). Якщо рядок не містить шуканого рядка, ви отримаєте повідомлення, і перший символ буде замінено.
— кудлатий

Це чудово, але, як воно стоїть, він може замінити лише 1 символ на 1 символ.
— Піт

3

Ви можете використовувати strrpos (), щоб знайти останню відповідність.

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

$string[$findChar]=".";

echo $string;

Вихід: малюнок_0007.значення


2

Стенограма прийнятої відповіді

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


0

Використовуйте "$" на виразі reg, щоб відповідати кінці рядка

$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
це працює лише в тому випадку, якщо остання поява в кінці рядка ideone.com/nbNSNq
— cawecoy

1
Це не спрацює, якщо після останньої "лисиці" з'являться інші символи.
— Джон Сондерсон,

0

Для зацікавлених: я написав функцію, яка використовує preg_match, щоб ви могли замінити з правого боку за допомогою 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;
}

Або як скорочення комбінації / реалізації обох варіантів:

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

на основі https://stackoverflow.com/a/3835653/3017716 та https://stackoverflow.com/a/23343396/3017716

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.