Я хочу, щоб версія, str_replace()що замінює лише перше виникнення $searchв $subject. Чи є просте рішення цього питання, чи мені потрібно хакітське рішення?
Я хочу, щоб версія, str_replace()що замінює лише перше виникнення $searchв $subject. Чи є просте рішення цього питання, чи мені потрібно хакітське рішення?
Відповіді:
Це можна зробити за допомогою preg_replace :
function str_replace_first($from, $to, $content)
{
$from = '/'.preg_quote($from, '/').'/';
return preg_replace($from, $to, $content, 1);
}
echo str_replace_first('abc', '123', 'abcdef abcdef abcdef');
// outputs '123def abcdef abcdef'
Магія полягає у необов'язковому четвертому параметрі [Limit]. З документації:
[Обмеження] - максимально можливі заміни для кожного шаблону в кожному предметному рядку. За замовчуванням до -1 (без обмеження).
Хоча дивіться відповідь зомба для більш ефективного методу (приблизно, у 3-4 рази швидше).
preg_quote? Наприклад, @ThomasRedstone побоюється, що роздільник /може бути небезпечним, якщо він з'явиться в $from, але, на щастя, це не так: він належним чином вийшов через preg_quoteдругий параметр 's (це можна легко перевірити). Мені буде цікаво дізнатися про конкретні проблеми (які могли б бути серйозними помилками безпеки PCRE в моїй книзі).
Немає його версії, але рішення зовсім не хакі.
$pos = strpos($haystack, $needle);
if ($pos !== false) {
$newstring = substr_replace($haystack, $replace, $pos, strlen($needle));
}
Досить просто та економить штраф за регулярні вирази.
Бонус: Якщо ви хочете замінити останнє явище, просто використовуйте strrposзамість strpos.
substr_replaceце є дещо громіздкою функцією, яка використовується завдяки всім параметрам, справжня проблема полягає в тому, що виконувати обробку рядків цифрами іноді досить складно - потрібно бути обережним, щоб передати правильну змінну / зміщення функції. Я фактично пішов би так далеко, щоб сказати, що наведений вище код є найпростішим, і, на мій погляд, логічним підходом.
Редагувати: обидві відповіді оновлено і тепер правильні. Я залишу відповідь, оскільки терміни функціонування все ще корисні.
На жаль, відповіді "zombat" і "too much php", на жаль, невірні. Це перегляд опублікованого відповіді zombat (оскільки мені не вистачає репутації, щоб розмістити коментар):
$pos = strpos($haystack,$needle);
if ($pos !== false) {
$newstring = substr_replace($haystack,$replace,$pos,strlen($needle));
}
Зверніть увагу на strlen ($ ігла), а не strlen ($ заміна). Приклад Zombat буде правильно працювати лише в тому випадку, якщо голка та заміна однакової довжини.
Ось такий же функціонал у функції з тією ж підписом, що і власний str_replace PHP:
function str_replace_first($search, $replace, $subject) {
$pos = strpos($subject, $search);
if ($pos !== false) {
return substr_replace($subject, $replace, $pos, strlen($search));
}
return $subject;
}
Це переглянута відповідь "занадто багато php":
implode($replace, explode($search, $subject, 2));
Зверніть увагу на 2 в кінці замість 1. Або у форматі функції:
function str_replace_first($search, $replace, $subject) {
return implode($replace, explode($search, $subject, 2));
}
Я приурочив дві функції, і перша вдвічі швидша, коли не знайдено відповідності. Вони мають однакову швидкість, коли знайдено відповідність.
stripos()на допомогу :-)
Мені було цікаво, хто з них найшвидший, тому я перевірив їх усіх.
Нижче ви знайдете:
Усі функції були протестовані з однаковими налаштуваннями:
$string = 'OOO.OOO.OOO.S';
$search = 'OOO';
$replace = 'B';
Функції, які замінюють лише перше виникнення рядка в рядку:
substr_replace($string, $replace, 0, strlen($search));
[CONTRIBUTED BY] => zombat
[OOO.OOO.OOO.S] => B.OOO.OOO.S
[AVERAGE TIME] => 0.0000062883
[SLOWER BY] => FASTESTreplace_first($search, $replace, $string);
[CONTRIBUTED BY] => too much php
[OOO.OOO.OOO.S] => B.OOO.OOO.S
[AVERAGE TIME] => 0.0000073902
[SLOWER BY] => 17.52%preg_replace($search, $replace, $string, 1);
[CONTRIBUTED BY] => karim79
[OOO.OOO.OOO.S] => B.OOO.OOO.S
[AVERAGE TIME] => 0.0000077519
[SLOWER BY] => 23.27%str_replace_once($search, $replace, $string);
[CONTRIBUTED BY] => happyhardik
[OOO.OOO.OOO.S] => B.OOO.OOO.S
[AVERAGE TIME] => 0.0000082286
[SLOWER BY] => 30.86%str_replace_limit($search, $replace, $string, $count, 1);
[CONTRIBUTED BY] => bfrohs - expanded renocor
[OOO.OOO.OOO.S] => B.OOO.OOO.S
[AVERAGE TIME] => 0.0000083342
[SLOWER BY] => 32.54%str_replace_limit($search, $replace, $string, 1);
[CONTRIBUTED BY] => renocor
[OOO.OOO.OOO.S] => B.OOO.OOO.S
[AVERAGE TIME] => 0.0000093116
[SLOWER BY] => 48.08%str_replace_limit($string, $search, $replace, 1, 0);
[CONTRIBUTED BY] => jayoaK
[OOO.OOO.OOO.S] => B.OOO.OOO.S
[AVERAGE TIME] => 0.0000093862
[SLOWER BY] => 49.26%Функції, які замінюють лише останнє виникнення рядка в рядку:
substr_replace($string, $replace, strrpos($string, $search), strlen($search));
[CONTRIBUTED BY] => oLinkSoftware - modified zombat
[OOO.OOO.OOO.S] => OOO.OOO.B.S
[AVERAGE TIME] => 0.0000068083
[SLOWER BY] => FASTESTstrrev(implode(strrev($replace), explode(strrev($search), strrev($string), 2)));
[CONTRIBUTED BY] => oLinkSoftware
[OOO.OOO.OOO.S] => OOO.OOO.B.S
[AVERAGE TIME] => 0.0000084460
[SLOWER BY] => 24.05%substr_replace()виграє результат, проста; тому що це внутрішня функція. Дві внутрішні та визначені користувачем функції відрізняються між собою за продуктивністю, оскільки внутрішня функціонує в нижчих шарах. Отже, чому б і ні preg_match()? Регулярні вирази майже повільніші, ніж кожна функція маніпуляції внутрішнім рядком, через їх націю шукати в рядку кілька разів.
substr_replace($string, $replace, 0, strlen($search));) не просто написав цю статику 0. Частина згортки нерегекс-рішень полягає в тому, що їм потрібно «знайти» вихідну точку, перш ніж знати, де її замінити.
На жаль, я не знаю жодної функції PHP, яка може це зробити.
Ви можете згорнути свій власний досить легко так:
function replace_first($find, $replace, $subject) {
// stolen from the comments at PHP.net/str_replace
// Splits $subject into an array of 2 items by $find,
// and then joins the array with $replace
return implode($replace, explode($find, $subject, 2));
}
return implode($replace, explode($find, $subject, $limit+1));для користувацьких номерів заміни
Я створив цю маленьку функцію, яка замінює рядок на рядку (залежно від регістру) лімітом, без необхідності Regexp. Це чудово працює.
function str_replace_limit($search, $replace, $string, $limit = 1) {
$pos = strpos($string, $search);
if ($pos === false) {
return $string;
}
$searchLen = strlen($search);
for ($i = 0; $i < $limit; $i++) {
$string = substr_replace($string, $replace, $pos, $searchLen);
$pos = strpos($string, $search);
if ($pos === false) {
break;
}
}
return $string;
}
Приклад використання:
$search = 'foo';
$replace = 'bar';
$string = 'foo wizard makes foo brew for evil foo and jack';
$limit = 2;
$replaced = str_replace_limit($search, $replace, $string, $limit);
echo $replaced;
// bar wizard makes bar brew for evil foo and jack
===falseзамість того, is_bool(щоб бути більш чітким - я віддаю цей великий палець лише тому, що він уникнув божевілля RegExp ! ... і в той же час це робоче і чисте рішення ...
preg_рішенню - це не божевілля, а особисті переваги. return preg_replace('/'.preg_quote($search, '/').'/', $replace, $content, 1);досить простий для читання людям, які не бояться регулярних виразів. Вам потрібен невідчутливий регістр пошуку? Додайте iпісля кінця роздільник візерунка. Потрібна підтримка unicode / multibyte? Додайте uпісля кінця роздільник візерунка. Вам потрібна підтримка межових слів? Додайте \bз обох сторін пошукової рядок. Якщо ви не хочете регулярного вираження, не використовуйте регулярний вираз. Коні на курси, але точно не божевілля.
Найпростішим способом було б використання регулярного вираження.
Інший спосіб - знайти позицію рядка з strpos (), а потім substr_replace ()
Але я б дійсно пішов на RegExp.
function str_replace_once($search, $replace, $subject) {
$pos = strpos($subject, $search);
if ($pos === false) {
return $subject;
}
return substr($subject, 0, $pos) . $replace . substr($subject, $pos + strlen($search));
}
=> КОД було переглянуто, тому вважайте деякі коментарі занадто старими
І дякую всім за те, що допомогли мені покращити це
Будь-яка помилка, будь ласка, повідомте мене; Я виправлю це відразу після
Отже, давайте:
Заміна першого "o" на "ea", наприклад:
$s='I love you';
$s=str_replace_first('o','ea',$s);
echo $s;
//output: I leave you
Функція:
function str_replace_first($a,$b,$s)
{
$w=strpos($s,$a);
if($w===false)return $s;
return substr($s,0,$w).$b.substr($s,$w+strlen($a));
}
substr($where,$b+strlen($this)), ні substr($where,$b+1). І я думаю, що substr_replaceце швидше.
$string = 'this is my world, not my world';
$find = 'world';
$replace = 'farm';
$result = preg_replace("/$find/",$replace,$string,1);
echo $result;
preg_quoteз , $findперш ніж використовувати його в якості вираження.
preg_quote(). Цю пізню дублюючу відповідь можна сміливо видалити зі сторінки, оскільки її поради надаються попередньою та більш високоприйнятою прийнятою відповіддю.
Щоб розширити відповідь на @ renocor , я написав функцію, яка на 100% сумісна із зворотним str_replace(). Тобто, ви можете замінити всі входження str_replace()з str_replace_limit()не псуючи нічого, навіть ті , використовуючи масиви для $search, $replaceі / або $subject.
Функція може бути повністю самодостатньою, якби ви хотіли замінити виклик функції на ($string===strval(intval(strval($string)))), але я б рекомендував проти неї, оскільки valid_integer()це досить корисна функція при роботі з цілими числами, наданими у вигляді рядків.
Примітка: Коли це можливо, замість цього str_replace_limit()використовуватиметься str_replace(), тож усі дзвінки str_replace()можна замінити на, str_replace_limit()не турбуючись про потрапляння на продуктивність.
<?php
$search = 'a';
$replace = 'b';
$subject = 'abcabc';
$limit = -1; // No limit
$new_string = str_replace_limit($search, $replace, $subject, $count, $limit);
echo $count.' replacements -- '.$new_string;
2 заміни - bbcbbc
$limit = 1; // Limit of 1
$new_string = str_replace_limit($search, $replace, $subject, $count, $limit);
echo $count.' replacements -- '.$new_string;
1 заміна - bbcabc
$limit = 10; // Limit of 10
$new_string = str_replace_limit($search, $replace, $subject, $count, $limit);
echo $count.' replacements -- '.$new_string;
2 заміни - bbcbbc
<?php
/**
* Checks if $string is a valid integer. Integers provided as strings (e.g. '2' vs 2)
* are also supported.
* @param mixed $string
* @return bool Returns boolean TRUE if string is a valid integer, or FALSE if it is not
*/
function valid_integer($string){
// 1. Cast as string (in case integer is provided)
// 1. Convert the string to an integer and back to a string
// 2. Check if identical (note: 'identical', NOT just 'equal')
// Note: TRUE, FALSE, and NULL $string values all return FALSE
$string = strval($string);
return ($string===strval(intval($string)));
}
/**
* Replace $limit occurences of the search string with the replacement string
* @param mixed $search The value being searched for, otherwise known as the needle. An
* array may be used to designate multiple needles.
* @param mixed $replace The replacement value that replaces found search values. An
* array may be used to designate multiple replacements.
* @param mixed $subject The string or array being searched and replaced on, otherwise
* known as the haystack. If subject is an array, then the search and replace is
* performed with every entry of subject, and the return value is an array as well.
* @param string $count If passed, this will be set to the number of replacements
* performed.
* @param int $limit The maximum possible replacements for each pattern in each subject
* string. Defaults to -1 (no limit).
* @return string This function returns a string with the replaced values.
*/
function str_replace_limit(
$search,
$replace,
$subject,
&$count,
$limit = -1
){
// Set some defaults
$count = 0;
// Invalid $limit provided. Throw a warning.
if(!valid_integer($limit)){
$backtrace = debug_backtrace();
trigger_error('Invalid $limit `'.$limit.'` provided to '.__function__.'() in '.
'`'.$backtrace[0]['file'].'` on line '.$backtrace[0]['line'].'. Expecting an '.
'integer', E_USER_WARNING);
return $subject;
}
// Invalid $limit provided. Throw a warning.
if($limit<-1){
$backtrace = debug_backtrace();
trigger_error('Invalid $limit `'.$limit.'` provided to '.__function__.'() in '.
'`'.$backtrace[0]['file'].'` on line '.$backtrace[0]['line'].'. Expecting -1 or '.
'a positive integer', E_USER_WARNING);
return $subject;
}
// No replacements necessary. Throw a notice as this was most likely not the intended
// use. And, if it was (e.g. part of a loop, setting $limit dynamically), it can be
// worked around by simply checking to see if $limit===0, and if it does, skip the
// function call (and set $count to 0, if applicable).
if($limit===0){
$backtrace = debug_backtrace();
trigger_error('Invalid $limit `'.$limit.'` provided to '.__function__.'() in '.
'`'.$backtrace[0]['file'].'` on line '.$backtrace[0]['line'].'. Expecting -1 or '.
'a positive integer', E_USER_NOTICE);
return $subject;
}
// Use str_replace() whenever possible (for performance reasons)
if($limit===-1){
return str_replace($search, $replace, $subject, $count);
}
if(is_array($subject)){
// Loop through $subject values and call this function for each one.
foreach($subject as $key => $this_subject){
// Skip values that are arrays (to match str_replace()).
if(!is_array($this_subject)){
// Call this function again for
$this_function = __FUNCTION__;
$subject[$key] = $this_function(
$search,
$replace,
$this_subject,
$this_count,
$limit
);
// Adjust $count
$count += $this_count;
// Adjust $limit, if not -1
if($limit!=-1){
$limit -= $this_count;
}
// Reached $limit, return $subject
if($limit===0){
return $subject;
}
}
}
return $subject;
} elseif(is_array($search)){
// Only treat $replace as an array if $search is also an array (to match str_replace())
// Clear keys of $search (to match str_replace()).
$search = array_values($search);
// Clear keys of $replace, if applicable (to match str_replace()).
if(is_array($replace)){
$replace = array_values($replace);
}
// Loop through $search array.
foreach($search as $key => $this_search){
// Don't support multi-dimensional arrays (to match str_replace()).
$this_search = strval($this_search);
// If $replace is an array, use the value of $replace[$key] as the replacement. If
// $replace[$key] doesn't exist, just an empty string (to match str_replace()).
if(is_array($replace)){
if(array_key_exists($key, $replace)){
$this_replace = strval($replace[$key]);
} else {
$this_replace = '';
}
} else {
$this_replace = strval($replace);
}
// Call this function again for
$this_function = __FUNCTION__;
$subject = $this_function(
$this_search,
$this_replace,
$subject,
$this_count,
$limit
);
// Adjust $count
$count += $this_count;
// Adjust $limit, if not -1
if($limit!=-1){
$limit -= $this_count;
}
// Reached $limit, return $subject
if($limit===0){
return $subject;
}
}
return $subject;
} else {
$search = strval($search);
$replace = strval($replace);
// Get position of first $search
$pos = strpos($subject, $search);
// Return $subject if $search cannot be found
if($pos===false){
return $subject;
}
// Get length of $search, to make proper replacement later on
$search_len = strlen($search);
// Loop until $search can no longer be found, or $limit is reached
for($i=0;(($i<$limit)||($limit===-1));$i++){
// Replace
$subject = substr_replace($subject, $replace, $pos, $search_len);
// Increase $count
$count++;
// Get location of next $search
$pos = strpos($subject, $search);
// Break out of loop if $needle
if($pos===false){
break;
}
}
// Return new $subject
return $subject;
}
}
E_USER_WARNINGпід всім , що є попередженням , НЕ помилка . Зворотний трек надзвичайно корисний для з'ясування того, який код передає недійсні дані в першу чергу функції (що абсолютно необхідно для відстеження помилок у виробництві). Що стосується повернення $subjectзамість false/ nullабо кидання помилки, це був просто особистий вибір для мого випадку використання. Для відповідності str_replace()функціональності найкраще скористатись уловлюваними фатальними помилками (як str_replace()це робиться при закритті перших двох аргументів).
preg_replace(). Крім того, preg_replace()/ regex пропонує обробку меж слів (якщо бажано) - те, що не-регулярні функції не забезпечують елегантності.
Відповідно до результатів тесту, я хотів би проголосувати за регулярний_вираз, який надає karim79. (У мене зараз недостатньо репутації, щоб проголосувати за це!)
Рішення від zombat використовує занадто багато функціональних викликів, я навіть спрощую коди. Я використовую PHP 5.4 для запуску обох рішень в 100 000 разів, і ось результат:
$str = 'Hello abc, have a nice day abc! abc!';
$pos = strpos($str, 'abc');
$str = substr_replace($str, '123', $pos, 3);
==> 1,85 сек
$str = 'Hello abc, have a nice day abc! abc!';
$str = preg_replace('/abc/', '123', $str, 1);
==> 1,35 сек
Як ви можете бачити. Продуктивність preg_replace не така вже й погана, як багато хто думає. Тому я б запропонував стильне рішення, якщо ваш регулярний експрес не є складним.
$posна false, так що, коли голка не існує в стозі сіна, це зашкодить вихід.
Щоб розширити відповідь на зомбат (що я вважаю найкращою відповіддю), я створив рекурсивну версію його функції, яка бере $limitпараметр, щоб вказати, скільки подій потрібно замінити.
function str_replace_limit($haystack, $needle, $replace, $limit, $start_pos = 0) {
if ($limit <= 0) {
return $haystack;
} else {
$pos = strpos($haystack,$needle,$start_pos);
if ($pos !== false) {
$newstring = substr_replace($haystack, $replace, $pos, strlen($needle));
return str_replace_limit($newstring, $needle, $replace, $limit-1, $pos+strlen($replace));
} else {
return $haystack;
}
}
}
$start_pos, тому , якщо він знаходиться за межами довжини рядка, то ця функція буде генерувати: Warning: strpos(): Offset not contained in string.... Ця функція не може зробити заміну, якщо $start_posвона перевищує довжину. Доказ відмови: 3v4l.org/qGuVIR ... Ваша функція може поєднувати return $haystackумови та уникати декларування змінних для одноразового використання, як це: 3v4l.org/Kdmqp Однак, як я вже говорив у коментарях в інших місцях на цій сторінці, я вважаю за краще використовувати дуже чистий, прямий, нерекурсивний preg_replace()дзвінок.
elseПостулати$start_pos > strlen($haystack) ? $start_pos = strlen($haystack) : '';
Для струни
$string = 'OOO.OOO.OOO.S';
$search = 'OOO';
$replace = 'B';
//replace ONLY FIRST occurance of "OOO" with "B"
$string = substr_replace($string,$replace,0,strlen($search));
//$string => B.OOO.OOO.S
//replace ONLY LAST occurance of "OOOO" with "B"
$string = substr_replace($string,$replace,strrpos($string,$search),strlen($search))
//$string => OOO.OOO.B.S
//replace ONLY LAST occurance of "OOOO" with "B"
$string = strrev(implode(strrev($replace),explode(strrev($search),strrev($string),2)))
//$string => OOO.OOO.B.S
Для одного персонажа
$string[strpos($string,$search)] = $replace;
//EXAMPLE
$string = 'O.O.O.O.S';
$search = 'O';
$replace = 'B';
//replace ONLY FIRST occurance of "O" with "B"
$string[strpos($string,$search)] = $replace;
//$string => B.O.O.O.S
//replace ONLY LAST occurance of "O" with "B"
$string[strrpos($string,$search)] = $replace;
// $string => B.O.O.B.S
substr_replace()методи пошкоджують вхідний рядок, коли значення пошуку немає. Доказ відмови: 3v4l.org/HmEml (І ця остання техніка з усіма revдзвінками серйозно перекручена / важко на очах.)
Доповнюючи сказане людьми, пам’ятайте, що весь рядок - це масив:
$string = "Lorem ipsum lá lá lá";
$string[0] = "B";
echo $string;
"Borem ipsum lá lá lá"
á. Демонстрація невдачі
stringє ваш багатобайтовий рядок, використовуючиmb_strlen($subject) != strlen($subject)
$str = "/property/details&id=202&test=123#tab-6p";
$position = strpos($str,"&");
echo substr_replace($str,"?",$position,1);
Використовуючи substr_replace, ми можемо замінити виникнення першого символу лише в рядку. як & повторюється кілька разів, але лише на першій позиції нам потрібно замінити & на?
Ця функція сильно натхненна відповіддю @renocor. Це робить функцію багатобайтової безпечною.
function str_replace_limit($search, $replace, $string, $limit)
{
$i = 0;
$searchLength = mb_strlen($search);
while(($pos = mb_strpos($string, $search)) !== false && $i < $limit)
{
$string = mb_substr_replace($string, $replace, $pos, $searchLength);
$i += 1;
}
return $string;
}
function mb_substr_replace($string, $replacement, $start, $length = null, $encoding = null)
{
$string = (array)$string;
$encoding = is_null($encoding) ? mb_internal_encoding() : $encoding;
$length = is_null($length) ? mb_strlen($string) - $start : $length;
$string = array_map(function($str) use ($replacement, $start, $length, $encoding){
$begin = mb_substr($str, 0, $start, $encoding);
$end = mb_substr($str, ($start + $length), mb_strlen($str), $encoding);
return $begin . $replacement . $end;
}, $string);
return ( count($string) === 1 ) ? $string[0] : $string;
}
Ви можете скористатися цим:
function str_replace_once($str_pattern, $str_replacement, $string){
if (strpos($string, $str_pattern) !== false){
$occurrence = strpos($string, $str_pattern);
return substr_replace($string, $str_replacement, strpos($string, $str_pattern), strlen($str_pattern));
}
return $string;
}
Знайшов цей приклад із php.net
Використання:
$string = "Thiz iz an examplz";
var_dump(str_replace_once('z','Z', $string));
Вихід:
ThiZ iz an examplz
Це може трохи зменшити продуктивність, але найпростіше рішення.
strpos()). Захищений, оскільки він не додає нової цінності на сторінку.
Якщо рядок не містить багатобайтових символів, і якщо ви хочете замінити лише один символ, ви можете просто використовувати strpos
Тут функція, яка обробляє помилки
/**
* Replace the first occurence of given string
*
* @param string $search a char to search in `$subject`
* @param string $replace a char to replace in `$subject`
* @param string $subject
* @return string
*
* @throws InvalidArgumentException if `$search` or `$replace` are invalid or if `$subject` is a multibytes string
*/
function str_replace_first(string $search , string $replace , string $subject) : string {
// check params
if(strlen($replace) != 1 || strlen($search) != 1) {
throw new InvalidArgumentException('$search & $replace must be char');
}elseif(mb_strlen($subject) != strlen($subject)){
throw new InvalidArgumentException('$subject is an multibytes string');
}
// search
$pos = strpos($subject, $search);
if($pos === false) {
// not found
return $subject;
}
// replace
$subject[$replace] = $subject;
return $subject;
}
Для петлевого рішення
<?php
echo replaceFirstMatchedChar("&", "?", "/property/details&id=202&test=123#tab-6");
function replaceFirstMatchedChar($searchChar, $replaceChar, $str)
{
for ($i = 0; $i < strlen($str); $i++) {
if ($str[$i] == $searchChar) {
$str[$i] = $replaceChar;
break;
}
}
return $str;
}
Ось простий клас, який я створив, щоб обернути наші трохи змінені функції str_replace () .
Наша функція php :: str_rreplace () також дозволяє здійснити зворотний, обмежений str_replace (), який може бути дуже зручним при спробі замінити лише остаточний екземпляр X рядка.
Обидва ці приклади використовують preg_replace () .
<?php
class php {
/**
* str_replace() from the end of a string that can also be limited e.g. replace only the last instance of '</div>' with ''
*
* @param string $find
* @param string $replace
* @param string $subject
* @param int $replacement_limit | -1 to replace all references
*
* @return string
*/
public static function str_replace($find, $replace, $subject, $replacement_limit = -1) {
$find_pattern = str_replace('/', '\/', $find);
return preg_replace('/' . $find_pattern . '/', $replace, $subject, $replacement_limit);
}
/**
* str_replace() from the end of a string that can also be limited e.g. replace only the last instance of '</div>' with ''
*
* @param string $find
* @param string $replace
* @param string $subject
* @param int $replacement_limit | -1 to replace all references
*
* @return string
*/
public static function str_rreplace($find, $replace, $subject, $replacement_limit = -1) {
return strrev( self::str_replace(strrev($find), strrev($replace), strrev($subject), $replacement_limit) );
}
}
$str = "Hello there folks!"
$str_ex = explode("there, $str, 2); //explodes $string just twice
//outputs: array ("Hello ", " folks")
$str_final = implode("", $str_ex); // glues above array together
// outputs: str("Hello folks")
Є ще один додатковий простір, але це не має значення, як це було для зворотного сценарію в моєму випадку.
це моя перша відповідь тут, я сподіваюсь це зробити правильно. Чому б не використати для цієї проблеми четвертий аргумент функції str_replace?
mixed str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] )
кількість: Якщо це буде зроблено, це буде встановлено кількість виконаних замін.
редагувати: Ця відповідь неправильна, тому що 4-й параметр str_replace є змінною, якій присвоюється кількість виконаних замін. Це суперечить preg_replace , який має 4-й параметр $limitі 5-й параметр &$count.
Неважко знайти рішення замінити лише першу чи першу пару примірників (давши значення підрахунку). Існує не так багато рішень для заміни останньої або останньої пари примірників.
Можливо, щось на зразок str_replace ($ find, $ substitu, $ subject, -3) має замінити останні три екземпляри.
У всякому разі, просто пропозиція.
s($subject)->replaceFirst($search)іs($subject)->replaceFirstIgnoreCase($search)корисні, як це знайдено в цій самостійній бібліотеці .