Skip to content

Commit

Permalink
Merge pull request #24 from bolt/fix/str_replace-in-multibyte-charact…
Browse files Browse the repository at this point in the history
…er-strings

Add `mb_substr_replace` method to correctly do replacements in multibyte character strings
  • Loading branch information
bobdenotter authored Nov 18, 2019
2 parents ca661b1 + 058c5b6 commit 515fd6e
Showing 1 changed file with 51 additions and 2 deletions.
53 changes: 51 additions & 2 deletions src/Str.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static function replaceFirst(string $subject, string $search, string $rep
return $subject;
}

return substr_replace($subject, $replace, $pos, mb_strlen($search));
return self::mb_substr_replace($subject, $replace, $pos, mb_strlen($search));
}

/**
Expand All @@ -41,7 +41,7 @@ public static function replaceLast(string $subject, string $search, string $repl
return $subject;
}

return substr_replace($subject, $replace, $pos, mb_strlen($search));
return self::mb_substr_replace($subject, $replace, $pos, mb_strlen($search));
}

/**
Expand Down Expand Up @@ -269,4 +269,53 @@ public static function generatePassword($length = 12)

return $str;
}

/**
* @see https://gist.github.com/stemar/8287074
*/
public static function mb_substr_replace($string, $replacement, $start, $length = null)
{
if (is_array($string)) {
$num = count($string);

// $replacement
$replacement = is_array($replacement) ? array_slice($replacement, 0, $num) : array_pad([$replacement], $num, $replacement);

// $start
if (is_array($start)) {
$start = array_slice($start, 0, $num);
foreach ($start as $key => $value) {
$start[$key] = is_int($value) ? $value : 0;
}
} else {
$start = array_pad([$start], $num, $start);
}

// $length
if (! isset($length)) {
$length = array_fill(0, $num, 0);
} elseif (is_array($length)) {
$length = array_slice($length, 0, $num);
foreach ($length as $key => $value) {
$length[$key] = isset($value) ? (is_int($value) ? $value : $num) : 0;
}
} else {
$length = array_pad([$length], $num, $length);
}

// Recursive call
return array_map(__FUNCTION__, $string, $replacement, $start, $length);
}

preg_match_all('/./us', (string) $string, $smatches);
preg_match_all('/./us', (string) $replacement, $rmatches);

if ($length === null) {
$length = mb_strlen($string);
}

array_splice($smatches[0], $start, $length, $rmatches[0]);

return implode($smatches[0]);
}
}

0 comments on commit 515fd6e

Please sign in to comment.