Eu quero uma versão str_replace()
que apenas substitua a primeira ocorrência de $search
no $subject
. Existe uma solução fácil para isso ou preciso de uma solução hacky?
Eu quero uma versão str_replace()
que apenas substitua a primeira ocorrência de $search
no $subject
. Existe uma solução fácil para isso ou preciso de uma solução hacky?
Respostas:
Pode ser feito com 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'
A mágica está no quarto parâmetro opcional [Limite]. A partir da documentação:
[Limite] - O número máximo de substituições possíveis para cada padrão em cada sequência de assunto. O padrão é -1 (sem limite).
Porém, veja a resposta do zombat para um método mais eficiente (aproximadamente, 3-4x mais rápido).
preg_quote
? Por exemplo, @ThomasRedstone teme que o delimitador /
possa ser perigoso se aparecer $from
, mas, felizmente, não é: ele escapou adequadamente por causa do preg_quote
segundo parâmetro do parâmetro (pode-se testá-lo facilmente). Eu gostaria de saber sobre problemas específicos (que seriam graves erros de segurança do PCRE no meu livro).
Não há versão, mas a solução não é hacky.
$pos = strpos($haystack, $needle);
if ($pos !== false) {
$newstring = substr_replace($haystack, $replace, $pos, strlen($needle));
}
Muito fácil e salva a penalidade de desempenho de expressões regulares.
Bônus: se você deseja substituir a última ocorrência, use apenas strrpos
no lugar de strpos
.
substr_replace
seja uma função um tanto difícil de usar devido a todos os parâmetros, o problema real é que a manipulação de seqüências de caracteres por números às vezes é complicada - é preciso ter cuidado para passar a variável / deslocamento correta para as funções. Na verdade, eu chegaria ao ponto de dizer que o código acima é a abordagem mais direta e, para mim, lógica.
Editar: as duas respostas foram atualizadas e agora estão corretas. Deixarei a resposta, pois os tempos das funções ainda são úteis.
Infelizmente, as respostas de 'zombat' e 'demais php' não estão corretas. Esta é uma revisão da resposta que o zombat postou (como eu não tenho reputação suficiente para postar um comentário):
$pos = strpos($haystack,$needle);
if ($pos !== false) {
$newstring = substr_replace($haystack,$replace,$pos,strlen($needle));
}
Observe o strlen ($ agulha), em vez de strlen ($ replace). O exemplo do Zombat só funcionará corretamente se a agulha e a substituição tiverem o mesmo comprimento.
Aqui está a mesma funcionalidade em uma função com a mesma assinatura que o próprio str_replace do 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;
}
Esta é a resposta revisada de 'muito php':
implode($replace, explode($search, $subject, 2));
Observe os 2 no final em vez de 1. Ou no formato da função:
function str_replace_first($search, $replace, $subject) {
return implode($replace, explode($search, $subject, 2));
}
Cronometrei as duas funções e a primeira é duas vezes mais rápida quando nenhuma correspondência é encontrada. Eles têm a mesma velocidade quando uma correspondência é encontrada.
stripos()
to the rescue :-)
Eu me perguntava qual era o mais rápido, então testei todos eles.
Abaixo você encontrará:
Todas as funções foram testadas com as mesmas configurações:
$string = 'OOO.OOO.OOO.S';
$search = 'OOO';
$replace = 'B';
Funções que substituem apenas a primeira ocorrência de uma sequência dentro de uma sequência:
substr_replace($string, $replace, 0, strlen($search));
[CONTRIBUTED BY] => zombat
[OOO.OOO.OOO.S] => B.OOO.OOO.S
[AVERAGE TIME] => 0.0000062883
[SLOWER BY] => FASTEST
replace_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%
Funções que substituem apenas a última ocorrência de uma sequência dentro de uma sequência:
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] => FASTEST
strrev(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()
ganha o resultado é simples; porque é uma função interna. Duas funções internas e definidas pelo usuário que fazem a mesma coisa diferem no desempenho, porque a interna é executada em camadas inferiores. Então porque não preg_match()
? Expressões regulares são quase mais lentas que todas as funções de manipulação interna de cadeias, devido à sua nação de pesquisar em uma cadeia várias vezes.
substr_replace($string, $replace, 0, strlen($search));
) não tenha apenas escrito essa estática 0
. Parte da convolução das soluções que não são regex é que elas precisam "encontrar" o ponto de partida antes de saber onde substituir.
Infelizmente, não conheço nenhuma função PHP que possa fazer isso.
Você pode rolar seus próprios facilmente assim:
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));
para números de substituição personalizados
Eu criei essa pequena função que substitui string em string (diferencia maiúsculas de minúsculas) por limit, sem a necessidade de Regexp. Funciona bem.
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;
}
Exemplo de uso:
$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
vez de is_bool(
ser mais explícito - estou desistindo, simplesmente porque evitou a loucura do RegExp ! ... e, ao mesmo tempo que está a trabalhar e limpa solução ...
preg_
solução facilmente personalizável não é loucura, mas uma preferência pessoal. return preg_replace('/'.preg_quote($search, '/').'/', $replace, $content, 1);
é muito simples de ler para pessoas que não temem regex. Precisa de pesquisa que não diferencia maiúsculas de minúsculas? Adicione i
após o delimitador de padrão final. Precisa de suporte unicode / multibyte? Adicione u
após o delimitador de padrão final. Precisa de suporte para limites de palavras? Adicione \b
nos dois lados da sua sequência de pesquisa. Se você não deseja regex, não use regex. Cavalos para cursos, mas certamente não loucura.
A maneira mais fácil seria usar a expressão regular.
A outra maneira é encontrar a posição da string com strpos () e, em seguida, um substr_replace ()
Mas eu realmente iria para o 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 CÓDIGO FOI REVISADO, portanto, considere alguns comentários muito antigos
E obrigado a todos por me ajudarem a melhorar isso
Qualquer erro, por favor me comunique; Eu vou consertar isso logo depois
Então, vamos para:
Substituindo o primeiro 'o' por 'ea', por exemplo:
$s='I love you';
$s=str_replace_first('o','ea',$s);
echo $s;
//output: I leave you
A função:
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))
, não substr($where,$b+1)
. E acho que substr_replace
é mais rápido.
$string = 'this is my world, not my world';
$find = 'world';
$replace = 'farm';
$result = preg_replace("/$find/",$replace,$string,1);
echo $result;
preg_quote
de $find
antes de usá-lo como uma expressão.
preg_quote()
. Esta resposta duplicada tardia pode ser removida com segurança da página porque seu conselho é fornecido pela resposta aceita anterior e com maior voto positivo.
Para expandir a resposta do @ renocor , escrevi uma função 100% compatível com versões anteriores str_replace()
. Ou seja, você pode substituir todas as ocorrências de str_replace()
com str_replace_limit()
sem mexer qualquer coisa, até mesmo aqueles que utilizam matrizes para o $search
, $replace
e / ou$subject
.
A função pode ser completamente independente, se você quiser substituir a chamada de função ($string===strval(intval(strval($string))))
, mas eu recomendo que ela valid_integer()
seja uma função bastante útil ao lidar com números inteiros fornecidos como seqüências de caracteres.
Nota: Sempre que possível, str_replace_limit()
será usado str_replace()
para que todas as chamadas para str_replace()
possam ser substituídas str_replace_limit()
sem se preocupar com um impacto no desempenho.
<?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 substituições - bbcbbc
$limit = 1; // Limit of 1
$new_string = str_replace_limit($search, $replace, $subject, $count, $limit);
echo $count.' replacements -- '.$new_string;
1 substituições - bbcabc
$limit = 10; // Limit of 10
$new_string = str_replace_limit($search, $replace, $subject, $count, $limit);
echo $count.' replacements -- '.$new_string;
2 substituições - 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
todo, o que é um aviso , não um erro . O backtrace é extremamente útil para descobrir qual código está passando os dados inválidos para a função em primeiro lugar (o que é absolutamente necessário para rastrear erros na produção). Quanto a retornar em $subject
vez de false
/ null
ou gerar um erro, essa foi simplesmente uma escolha pessoal para o meu caso de uso. Para combinar com str_replace()
a funcionalidade, usar erros fatais capturáveis seria a melhor aposta (como str_replace()
acontece ao fornecer um encerramento para os dois primeiros argumentos).
preg_replace()
. Além disso, preg_replace()
/ regex oferece manipulação de limites de palavras (se desejável) - algo que as funções que não sejam de regex não fornecerão elegantemente.
De acordo com o resultado do meu teste, gostaria de votar no regular_express fornecido por karim79. (Não tenho reputação suficiente para votar agora!)
A solução do zombat usa muitas chamadas de funções, até simplifico os códigos. Estou usando o PHP 5.4 para executar as duas soluções 100.000 vezes, e aqui está o resultado:
$str = 'Hello abc, have a nice day abc! abc!';
$pos = strpos($str, 'abc');
$str = substr_replace($str, '123', $pos, 3);
==> 1,85 s
$str = 'Hello abc, have a nice day abc! abc!';
$str = preg_replace('/abc/', '123', $str, 1);
==> 1,35 s
Como você pode ver. O desempenho do preg_replace não é tão ruim quanto muitas pessoas pensam. Então, eu sugiro a solução elegante se o seu expresso regular não for complicado.
$pos
para false
, então, quando a agulha não existe no palheiro, ele irá danificar a saída.
Para expandir a resposta do zombat (que acredito ser a melhor resposta), criei uma versão recursiva de sua função que usa um $limit
parâmetro para especificar quantas ocorrências você deseja substituir.
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
, por isso, se ele está fora do comprimento da corda, esta função irá gerar: Warning: strpos(): Offset not contained in string...
. Essa função falha ao fazer uma substituição quando $start_pos
está além do comprimento. Prova de falha: 3v4l.org/qGuVIR ... Sua função pode combinar as return $haystack
condições e evitar a declaração de variáveis de uso único como esta: 3v4l.org/Kdmqp No entanto, como já disse em comentários em outros lugares desta página, prefiro use uma preg_replace()
chamada muito limpa, direta e não recursiva .
else
statment$start_pos > strlen($haystack) ? $start_pos = strlen($haystack) : '';
Para uma string
$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
Para um único caractere
$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()
técnicas danificam a sequência de entrada quando o valor da pesquisa não está presente. Prova do fracasso: 3v4l.org/HmEml (E essa última técnica com todas as rev
chamadas está seriamente complicada / difícil para os olhos.)
Complementando o que as pessoas disseram, lembre-se de que toda a cadeia é uma matriz:
$string = "Lorem ipsum lá lá lá";
$string[0] = "B";
echo $string;
"Borem ipsum lá lá lá"
á
. Demonstração de fracasso
string
é uma string de vários bytes usandomb_strlen($subject) != strlen($subject)
$str = "/property/details&id=202&test=123#tab-6p";
$position = strpos($str,"&");
echo substr_replace($str,"?",$position,1);
Usando substr_replace, podemos substituir a ocorrência do primeiro caractere apenas na string. como & é repetido várias vezes, mas somente na primeira posição temos que substituir & por?
Esta função é fortemente inspirada na resposta de @renocor. Torna a função multi byte segura.
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;
}
Você pode usar isto:
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;
}
Encontrei este exemplo em php.net
Uso:
$string = "Thiz iz an examplz";
var_dump(str_replace_once('z','Z', $string));
Resultado:
ThiZ iz an examplz
Isso pode reduzir um pouco o desempenho, mas a solução mais fácil.
strpos()
). Voto negativo porque não adiciona nenhum novo valor à página.
Se a sequência não contiver caracteres multibyte e se você quiser substituir apenas um caractere, poderá simplesmente usar strpos
Aqui uma função que lida com erros
/**
* 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;
}
Solução For Loop
<?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;
}
Aqui está uma classe simples que eu criei para agrupar nossas funções str_replace () ligeiramente modificadas .
Nossa função php :: str_rreplace () também permite executar um str_replace () reverso e limitado, o que pode ser muito útil ao tentar substituir apenas as instâncias X finais de uma string.
Esses exemplos usam 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")
Há mais um espaço adicional, mas não importava como era para o script de backgound no meu caso.
esta é a minha primeira resposta aqui, espero fazê-lo corretamente. Por que não usar o quarto argumento da função str_replace para esse problema?
mixed str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] )
count: se aprovado, será definido como o número de substituições realizadas.
edit: Esta resposta está errada, porque o quarto parâmetro de str_replace é uma variável que recebe o número de substituições efetuadas. Isso é inconsistente com preg_replace , que possui um 4º parâmetro $limit
e um 5º parâmetro &$count
.
É fácil encontrar uma solução para substituir apenas a primeira ou a primeira instância (fornecendo o valor da contagem). Não há muitas soluções para substituir a última ou a última instância.
Talvez algo como str_replace ($ find, $ replace, $ subject, -3) deva substituir as três últimas instâncias.
Enfim, apenas uma sugestão.
s($subject)->replaceFirst($search)
es($subject)->replaceFirstIgnoreCase($search)
útil, como encontrado nesta biblioteca autônoma .