How To Replace Only The First Occurance Of A String In PHP?

Discover how to replace only the first matching string from another string in PHP

  • By Daniyal Hamid
  • July 01, 2018
  • Comments
In This Article

PHP's str_replace() by default replaces all occurances of a match; an optional fourth argument (if supplied) to the function gives the number of replacements performed, and does not help in limiting the number of replacements that will be made. In instances where we only want to replace the first occurance of a match, you could use any one of the techniques mentioned in this article. For all the examples in this article, we'll be using the following string to replace the first occurance of foo:

$str = 'foobar foobaz fooqux';

Using preg_replace()

The preg_replace() method has an optional fourth argument, that takes in a number to limit the number of replaces made based on the regular expression pattern. It has the following syntax:

// PHP 4+
preg_replace($pattern, $replacement, $string, $limit);

The limit parameter defaults to -1 which means no limit. In order to only replace the first occurance of the string we could do the following:

$replaceWith = '';
$findStr = 'foo';

echo preg_replace('/' . $findStr . '/', $replaceWith, $str, 1);

// output: "bar foobaz fooqux"

Remember to wrap your regular expression pattern within two forward brackets (e.g. /pattern/) and use preg_quote() method if you're using dynamic patterns, for example:

$replaceWith = '';
$pattern = '.foo.bar';

echo preg_replace('/' . preg_quote($pattern) . '/', $replaceWith, $str, 1);

// since there will be no matches found with this $pattern, the output will be:
// "foobar foobaz fooqux"

When using preg_quote() remember that only \ + * ? [ ^ ] $ ( ) { } = ! < > | : - get escaped. Keep in mind that / is not a special regular expression character, so if your pattern has it, simply supply it as the second argument to preg_quote (as the delimeter), like so: preg_quote($pattern, '/').

Replacing First Match From Multiple Patterns Using preg_replace():

The first argument to the preg_replace() function can either be a string pattern or an array of string patterns. If an array of patterns is provided then to replace the first match of each pattern we can do the following:

$replaceWith = '';

echo preg_replace(['/foo/', '/baz/'], $replaceWith, $str, 1);

// output: "bar foo fooqux"

Using substr_replace()

The substr_replace() function has the following syntax:

// PHP 4+
substr_replace($string, $replacement, $startOffset, $length);

The last two parameters of the substr_replace() function (i.e. the starting offset of the match and the length of the portion of string which is to be replaced) can be used to ensure only the whole string (that's of concern to us) is replaced, and only once. Consider the following example:

$replaceWith = '';

$findStr = 'foo';
$pos = strpos($str, $findStr);

if ($pos !== false) {
    $str = substr_replace($str, $replaceWith, $pos, strlen($findStr));
}

echo $str;

// output: "bar foobaz fooqux"

Using implode() And explode()

Using the third argument to explode() function, we can ensure we only split the array once at the first match. Consider the following (complete) syntax of the explode() function:

// PHP 4+
explode($delimeter, $str, $limit);

When a positive value is supplied as the $limit, the returned array will contain a maximum of $limit elements with the last element containing the rest of string. For example, if limit is set to 2, then the returned array will contain ONE matching element with the last element containing the rest of the string.

With that knowledge, consider the example below:

$replaceWith = '';
$findStr = 'foo';

print_r(explode($findStr, $str, 2));

// output: Array ([0] => "" [1] => "bar foobaz fooqux")

Now with that result, we can simply use implode() to join the string back using the replace-with value like so:

$replaceWith = '';
$findStr = 'foo';

echo implode($replaceWith, explode($findStr, $str, 2));

// output: "bar foobaz fooqux"

There are of course other ways that this can be done, but these are our picks for this topic. If you have something to add, please let us know in the comments section.