php 使用 str_replace 使其仅作用于第一个匹配项?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1252693/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 01:44:59  来源:igfitidea点击:

Using str_replace so that it only acts on the first match?

phpstring

提问by Nick Heiner

I want a version of str_replace()that only replaces the first occurrence of $searchin the $subject. Is there an easy solution to this, or do I need a hacky solution?

我想的一个版本str_replace()是只替换第一次出现$search$subject。有没有一个简单的解决方案,或者我需要一个hacky解决方案?

回答by zombat

There's no version of it, but the solution isn't hacky at all.

没有它的版本,但解决方案一点也不笨拙。

$pos = strpos($haystack, $needle);
if ($pos !== false) {
    $newstring = substr_replace($haystack, $replace, $pos, strlen($needle));
}

Pretty easy, and saves the performance penalty of regular expressions.

非常简单,并节省了正则表达式的性能损失。


Bonus: If you want to replace lastoccurrence, just use strrposin place of strpos.


奖励:如果你想替换最后一次出现,只需使用strrpos代替strpos.

回答by karim79

Can be done with preg_replace:

可以用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'

The magic is in the optional fourth parameter [Limit]. From the documentation:

神奇之处在于可选的第四个参数 [Limit]。从文档:

[Limit] - The maximum possible replacements for each pattern in each subject string. Defaults to -1 (no limit).

[限制] - 每个主题字符串中每个模式的最大可能替换。默认为 -1(无限制)。


Though, see zombat's answerfor a more efficient method (roughly, 3-4x faster).


不过,请参阅zombat 的答案以了解更有效的方法(大约快 3-4 倍)。

回答by Bas

Edit: both answers have been updated and are now correct. I'll leave the answer since the function timings are still useful.

编辑:两个答案都已更新,现在是正确的。我会留下答案,因为功能计时仍然有用。

The answers by 'zombat' and 'too much php' are unfortunately not correct. This is a revision to the answer zombat posted (as I don't have enough reputation to post a comment):

不幸的是,'zombat' 和 'too much php' 的答案是不正确的。这是对 zombat 发布的答案的修订(因为我没有足够的声誉发表评论):

$pos = strpos($haystack,$needle);
if ($pos !== false) {
    $newstring = substr_replace($haystack,$replace,$pos,strlen($needle));
}

Note the strlen($needle), instead of strlen($replace). Zombat's example will only work correctly if needle and replace are the same length.

注意 strlen($needle),而不是 strlen($replace)。Zombat 的示例只有在针和替换的长度相同时才能正常工作。

Here's the same functionality in a function with the same signature as PHP's own str_replace:

这是与 PHP 自己的 str_replace 具有相同签名的函数中的相同功能:

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

This is the revised answer of 'too much php':

这是'太多php'的修订答案:

implode($replace, explode($search, $subject, 2));

Note the 2 at the end instead of 1. Or in function format:

注意末尾的 2 而不是 1。 或者在函数格式中:

function str_replace_first($search, $replace, $subject) {
    return implode($replace, explode($search, $subject, 2));
}

I timed the two functions and the first one is twice as fast when no match is found. They are the same speed when a match is found.

我为这两个函数计时,当找不到匹配项时,第一个函数的速度是它的两倍。当找到匹配时,它们的速度相同。

回答by oLinkWebDevelopment

I wondered which one was the fastest, so I tested them all.

我想知道哪个最快,所以我测试了它们。

Below you will find:

下面你会发现:

  • A comprehensive list of all the functions that have been contributed onto this page
  • Benchmark testing for each contrubution (average execution time over 10,000 runs)
  • Links to each answer (for the full code)
  • 已贡献到此页面的所有功能的完整列表
  • 每个 contrubution 的基准测试(平均执行时间超过 10,000 次运行)
  • 每个答案的链接(完整代码)


All functions were tested with the same settings:

所有功能都使用相同的设置进行测试:

$string = 'OOO.OOO.OOO.S';
$search = 'OOO'; 
$replace = 'B';


Functions that only replace the firstoccurrence of a string within a string:

仅替换字符串中第一次出现的字符串的函数:



Functions that only replace the lastoccurrence of a string within a string:

仅替换字符串中最后一次出现的字符串的函数:

回答by too much php

Unfortunately, I don't know of any PHP function which can do this.
You can roll your own fairly easily like this:

不幸的是,我不知道有任何 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));
}

回答by Parziphal

I created this littlefunction that replaces string on string (case-sensitive) with limit, without the need of Regexp. It works fine.

我创建了这个函数,它用限制替换字符串上的字符串(区分大小写),不需要正则表达式。它工作正常。

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

Example usage:

用法示例:

$search  = 'foo';
$replace = 'bar';
$string  = 'foo wizard makes foo brew for evil foo and Hyman';
$limit   = 2;

$replaced = str_replace_limit($search, $replace, $string, $limit);

echo $replaced;
// bar wizard makes bar brew for evil foo and Hyman

回答by luchaninov

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

回答by PYK

=> CODE WAS REVISED, so consider some comments too old

=> 代码已修改,因此请考虑一些过时的评论

And thanks everyoneon helping me to improve that

Any BUG, please communicate me; I'll fix that up right after

感谢大家帮助我改进

有BUG请私信我;我会马上解决这个问题

So, lets go for:

所以,让我们去:

Replacing the first 'o'to 'ea'for example:

例如,将第一个'o'替换为'ea'

$s='I love you';
$s=str_replace_first('o','ea',$s);
echo $s;

//output: I leave you

The function:

功能:

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

回答by Rufinus

The easiest way would be to use regular expression.

最简单的方法是使用正则表达式。

The other way is to find the position of the string with strpos() and then an substr_replace()

另一种方法是使用 strpos() 找到字符串的位置,然后使用 substr_replace()

But i would really go for the RegExp.

但我真的会选择 RegExp。

回答by zack

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