Php 基于索引的多字符串替换

Php 基于索引的多字符串替换,php,string,replace,str-replace,Php,String,Replace,Str Replace,我需要根据索引替换字符串的多个部分 $string = '01234567890123456789'; $replacements = array( array(3, 2, 'test'), array(8, 2, 'haha') ); $expected_result = '012test567haha0123456789'; $replacements中的索引不应重叠 我一直在尝试编写自己的解决方案,根据需要替换或不需要替换的部分将原始阵列拆分为多个部分,最后将它们合

我需要根据索引替换字符串的多个部分

$string  = '01234567890123456789';

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

$expected_result = '012test567haha0123456789';
$replacements
中的索引不应重叠

我一直在尝试编写自己的解决方案,根据需要替换或不需要替换的部分将原始阵列拆分为多个部分,最后将它们合并:

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;
}
echo str_替换_为_索引($string,$replacements);
//输出预期结果“012test567haha0123456789”
函数str_replace_与_索引($string,$replacements){
$string\u chars=str\u split($string);
$string_sections=array();
$replacement=false;
$section=0;
foreach($string\u chars as$char\u idx=>$char){
if($replacement!=($r_idx=replacement($replacements,$char_idx))!==false)){
$replacement=!$replacement;
$section++;
}
$string_sections[$section]=$string_sections[$section]?$string_sections[$section]:数组();
$string_sections[$section]['original'].=$char;
如果($replacement)$string_sections[$section]['new']=$replacements[$r_idx][2];
}
$string_result='';
foreach($s){
$string_result.=($s['new'])?$s['new']:$s['original'];
}
返回$string\u结果;
}
函数替换($replacements,$idx){
foreach($r_idx=>$r替换){
如果($idx>=$r[0]&&$idx<$r[0]+$r[1]){
返回$r_idx;
}
}
返回false;
}
有没有更有效的方法达到同样的效果

上面的解决方案看起来并不优雅,而且替换字符串的时间也很长。

使用此解决方案

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

$rep
缺少需要替换的字符长度。这仅替换每个
$rep
的1个字符。您可以将$repeat设置为每个字符的重复次数
$repeat=1获取我
12test4567hahaa9123456789
<代码>$repeat=2获取我
12test4567hahaa912test4567hahaa9
。每个
$rep
需要替换的字符数可能不同,但不是固定的。hmm。。为了清楚起见,
$rep
中的“3”和“8”应该是
$str
中的索引,而不是要替换的子字符串。它不是<代码>数组(3,2,'test')
的意思是:从第三个索引开始,最多两个字符,替换为'test'(四个字符)。在这种情况下,
strlen()
将增加2。