I want to write an application that reverses all the words of input text, but all non-letter symbols should stay in the same places.
What I already have:
function reverse($string)
{
$reversedString = '';
for ($position = strlen($string); $position > 0; $position--) {
$reversedString .= $string[$position - 1]; //.= - concatenation assignment, привязывает b to a;
}
return $reversedString;
}
$name = 'ab1 ab2';
print_r(reverse($name));
And how to write a fucntion, that return text without affecting any special characters? Output should be: "ab1 ab2" => "ba1 ba2"
CodePudding user response:
preg_replace_callback()
is the perfect, native, one-liner for this task.
Code: (Demo)
$name = 'ab1 ab2';
echo preg_replace_callback('/[a-z] /i', fn($m) => strrev($m[0]), $name);
// ba1 ba2
Match one or more letters, replace each sequence of letters with the reversed version of itself.
CodePudding user response:
If I understood your problem correctly, then the solution below will probably be able to help you. This solution is not neat and not optimal, but it seems to work:
function reverse(string $string): string
{
$reversedStrings = explode(" ", $string);
foreach ($reversedStrings as &$word) {
$chars = mb_str_split($word, 1);
$filteredChars = [];
foreach (array_reverse($chars) as $char) {
if (ctype_alpha($char)) {
$filteredChars[] = $char;
}
}
foreach ($chars as &$char) {
if (!ctype_alpha($char)) {
continue;
}
$char = array_shift($filteredChars);
}
$word = implode("", $chars);
}
return implode(" ", $reversedStrings);
}
$name = "ab1 ab2 ab! ab. Hello!789World! qwe4rty5";
print_r(reverse($name)); // => "ba1 ba2 ba! ba. dlroW!789olleH! ytr4ewq5"
In the example, non-alphabetic characters do not change their position within the word. Example: "Hello!789World! qwe4rty5" => "dlroW!789olleH! ytr4ewq5".
CodePudding user response:
STEPS
- Filter alphabetic
$aplha
and non-alphabetic characters$nonAlpha
. - Reverse the alphabetic characters
$reversed
. - Push/insert the non-alphabetic characters
$nonAlpha
into the$reversed
array while preserving the original non-alphabetic positions.
function strReverse(string $text): string
{
$nonAlpha = [];
$alpha = [];
$mbStrSplit = mb_str_split($text);
array_walk($mbStrSplit, function ($v, $k) use (&$nonAlpha, &$alpha) {
if (mb_ereg_match("[^a-z]", $v, "i")) {
$nonAlpha[$k] = $v;
} else {
$alpha[] = $v;
}
});
$reversed = array_reverse($alpha);
array_walk($nonAlpha, function ($v, $k) use (&$reversed) {
array_splice($reversed, $k, 0, $v);
});
return implode("", $reversed);
}
var_export(strReverse("ab1 ab2")); // "ba1 ba2"
var_export(strReverse("ab1baa")); // "aa1bba"