0

I need to replace multiple sections of a string based on their indices.

$string  = '01234567890123456789';

$replacements = array(
    array(3, 2, 'test'),
    array(8, 2, 'haha')
);

$expected_result = '012test567haha0123456789';

Indices in $replacements are expected not to have overlaps.

I have been trying to write my own solution, split the original array into multiple pieces based on sections which needs to be replaced or not, and finally combine them:

echo str_replace_with_indices($string, $replacements);
// outputs the expected result '012test567haha0123456789'

function str_replace_with_indices ($string, $replacements) {
    $string_chars = str_split($string);

    $string_sections = array();
    $replacing = false;
    $section = 0;
    foreach($string_chars as $char_idx => $char) {
        if ($replacing != (($r_idx = replacing($replacements, $char_idx)) !== false)) {
            $replacing = !$replacing;
            $section++;
        }
        $string_sections[$section] = $string_sections[$section] ? $string_sections[$section] : array();
        $string_sections[$section]['original'] .= $char;
        if ($replacing) $string_sections[$section]['new'] = $replacements[$r_idx][2];
    }

    $string_result = '';
    foreach($string_sections as $s) {
        $string_result .= ($s['new']) ? $s['new'] : $s['original'];
    }

    return $string_result; 
}

function replacing($replacements, $idx) {
   foreach($replacements as $r_idx => $r) {
       if ($idx >= $r[0] && $idx < $r[0]+$r[1]) {
           return $r_idx;
       }
   }
   return false;
}

Is there any more effective way to achieve the same result?

The above solution doesn't look elegant and feels quite long for string replacement.

0

1 Answer 1

2

Use this

$str = '01234567890123456789';
$rep = array(array(3,3,'test'), array(8,2,'haha'));
$index = 0;
$ctr = 0;
$index_strlen = 0;
foreach($rep as $s)
{
   $index = $s[0]+$index_strlen;

   $str = substr_replace($str, $s[2], $index, $s[1]);

   $index_strlen += strlen($s[2]) - $s[1];
}
echo $str;
Sign up to request clarification or add additional context in comments.

6 Comments

$rep is missing length of characters needs to be replaced. This only replaces 1 character for each $rep.
you set $repeat to number of repeats for each char
$repeat = 1; gets me 12test4567haha9123456789. $repeat = 2; gets me 12test4567haha912test4567haha9. And the number of characters needs to be replaced can be different for each $rep, not fixed.
hmm.. to be clear, '3' and '8' in $rep should be indices in $str, not substring to replace.
It is not. array(3, 2, 'test') means: starting from the third index as many as two characters, replace with 'test' (four characters). In this case, strlen() will increase by 2.
|

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.