Arthur Halma
Arthur Halma

Reputation: 4001

preg_replace all occurrences in string withing defined delimeters

I am trying to replace all occurrences of "a" with "b" inside some string. Problem is that I need to replace only those letters which are inside brackets:

asd asd asd [asd asd asd] asd asd asd

For now I have this code:

$what = '/(?<=\[)a(?=.*?\])/s';
$with = 'b';
$where = 'asd asd asd [asd asd asd] asd asd asd';

But it only replaces the first "a", and I am getting this result:

asd asd asd [bsd asd asd] asd asd asd

I realy need to done this only with one preg_replace call.

Upvotes: 1

Views: 11141

Answers (2)

Jon
Jon

Reputation: 437336

You cannot do this with a single preg_replace call because the lookbehind would need to say "there is an opening square bracket somewhere before the match" and that is impossible since lookbehind patterns must have fixed length.

Why would you absolutely need to do this in one call anyway? It is doable pretty easily with preg_replace_callback, where you would match groups of content inside square brackets and use preg_replace on the match each time (or just a simple str_replace if all you are going to do is replace "a" with "b").

Example:

$what = '/\[([^]]*)\]/';
$where = 'asd asd asd [asd asd asd] asd asd asd';

echo preg_replace_callback(
    $what, 
    function($match) {
        return '['.str_replace('a', 'b', $match[1]).']';
    },
    $where);

Upvotes: 2

user1646111
user1646111

Reputation:

Try this (This what exactly Jon explained)

function replace_a_with_b($matches)
{
  return str_replace("a", "b", $matches[0]);
}
$text = 'asd asd asd [asd asd asd] asd asd asd';
echo preg_replace_callback("#(\[[^]]+\])#", "replace_a_with_b", $text);

Output:

asd asd asd [bsd bsd bsd] asd asd asd

Upvotes: 3

Related Questions