2

I am trying to achieve the following:

$subject = 'a b a';
$search = 'a';
$replace = '1';

Desired result:

Array
(
[0] => 1 b a
[1] => a b 1
)

Is there any way of achieving this with preg_replace?

preg_replace('/\b'.$search.'(?=\s+|$)/u', $replace, array($subject));

will return all the replacments in the same result:

Array
(
[0] => 1 b 1
)

Cheers

2
  • I think I'm losing it ;) Why exactly do you pass $subject as an array? Commented Dec 1, 2009 at 13:11
  • preg_replace can return a string or an array depending on the type of $subject. Commented Dec 1, 2009 at 14:49

2 Answers 2

1

I think it is not possible. You can specify a limit of replacements in the optional fourth parameter, but that always starts at the beginning.

It could be possible to achieve what you're looking for with preg_split(). You would just have to split your string on all occasions of your search pattern and then mess with them one by one. If your search pattern is just a simple string, you can achieve the same with explode(). If you need help figuring this approach out, I'll be happy to help.

EDIT: Let's see if this works for you:

$subject = 'a b a';
$pattern = '/a/';
$replace = 1;

// We split the string up on all of its matches and obtain the matches, too
$parts = preg_split($pattern, $subject);
preg_match_all($pattern, $subject, $matches);

$numParts = count($parts);
$results = array();

for ($i = 1; $i < $numParts; $i++)
{
    // We're modifying a copy of the parts every time
    $partsCopy = $parts;

    // First, replace one of the matches
    $partsCopy[$i] = $replace.$partsCopy[$i];

    // Prepend the matching string to those parts that are not supposed to be replaced yet
    foreach ($partsCopy as $index => &$value)
    {
        if ($index != $i && $index != 0)
            $value = $matches[0][$index - 1].$value;
    }

    // Bring it all back together now
    $results[] = implode('', $partsCopy);
}

print_r($results);

Note: This is not tested yet. Please report whether it works.

EDIT 2:

I tested it with your example now, fixed a few things and it works now (at least with that example).

Sign up to request clarification or add additional context in comments.

Comments

1
function multipleReplace($search,$subject,$replace) {
    preg_match_all($search, $subject,$matches,PREG_OFFSET_CAPTURE);
    foreach($matches as $match) {
    if (is_array($match)) {
        foreach ($match as $submatch) {
        list($string,$start) = $submatch;
        $length = strlen($string);
        $val = "";
        if ($start - 1 > 0) {
            $val .= substr($subject,0,$start);
        }
        $val .= preg_replace($search,$string,$replace);
        $val .= substr($subject,$start + $length);
        $ret[] = $val;
        }
    }
    }
    return $ret;
}

$search = 'a';

print_r(multipleReplace('/\b'.$search.'(?=\s+|$)/u','a b a','1'));

Output

Array
(
    [0] => 1 b a
    [1] => a b 1
)

1 Comment

This would not always work as replacing in substrings is not equal to replacing in the full string. But that could of course be worked around. This is just a hint as to what you will have to do to get it working.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.