-2

How can I exchange the first letter and the last letter in PHP ?

For e.g, if the string is "hello", the result must be "oellh". I used str_replace , but I can replace only one word. Here is my code:

$string="hello";
$first=$string[0];
$last=substr($string, -1);
$result=str_replace($first, $last, $string);
echo $result;
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Ivy
  • 21
  • 5

6 Answers6

2

Approaches using built-in standard string functions or array bracket character position reference will run into trouble if your string contains multibyte characters. There's a very simple one-line-way to do this swap for multibyte (or any) strings – without multiple function calls or temporary variables. You can use preg_replace with the u Unicode flag:

function swap_first_last(string $str): string
{
    return preg_replace('~^(.)(.*)(.)$~u', '\3\2\1', $str);
}

echo swap_first_last('foobar'); // (foobar > roobaf)
echo swap_first_last('फोबर'); // रोबफ (phobara > robapha)

In the regular expression, ^ stands for start of subject, then (.) captures the first character, (.*) captures 0 or more characters in between, (.) captures the final character, with $ for end of subject. Finally, with '\3\2\1', we simply reverse the first and last capture groups.


On using bracket string access $str[0] and $str[-1], from the manual: "Internally, PHP strings are byte arrays. As a result, accessing or modifying a string using array brackets is not multi-byte safe, and should only be done with strings that are in a single-byte encoding such as ISO-8859-1."

On using built-in standard string functions, from the manual: "If you apply a non-multibyte-aware string function to the string, it probably fails to detect the beginning or ending of the multibyte character and ends up with a corrupted garbage string that most likely loses its original meaning."

Therefore, for a potential multibyte string, you should use multibyte string functions such as mb_substr(), mb_strlen() and mb_str_split(), depending on your approach. I personally find the preg_replace() solution much simpler and more readable.

Markus AO
  • 4,771
  • 2
  • 18
  • 29
  • @mickmackusa have done. I'm still hoping that one day we get ourselves a "merge" feature... – Markus AO May 27 '23 at 12:20
  • Merging pages already exists, but we shouldn't need it for newly asked questions if contributors close the new question and answer the old one. – mickmackusa May 27 '23 at 13:07
1

Split the string using str_split and put them in an array. Now grab the last element, put it front , get the remaining elements in the between using array_slice and append the first element to the tail.

<?php
$str='hello';
echo $newstr=$str[count(str_split($str))-1].implode('',array_slice(str_split($str),1,count(str_split($str))-2)).str_split($str)[0];

OUTPUT :

oellh
Shankar Narayana Damodaran
  • 68,075
  • 43
  • 96
  • 126
  • This approach is very convoluted (versus a single regex) and [will not work properly on a single-character string or a string containing multibyte characters](https://3v4l.org/VgCBl). – mickmackusa May 24 '23 at 22:20
1

Well,

  1. Take the last character and put it first;
  2. take the middle characters and put them in the middle;
  3. and take the first character and put it last.

Like so:

$string = 'hello';
$length = strlen($string);
$newStr = $string[$length-1] . substr($string, 1, $length-2) . $string[0];
echo $newStr; // oellh

Accounting for zero/one/two-character words may also be a good idea:

$string = 'hello';
$length = strlen($string);
$newStr = '';
switch ($length) {
    case 0:
    case 1:
        $newStr = $string;
        break;
    case 2:
        $newStr = strrev($string);
        break;
    default:
        $newStr = $string[$length-1] . substr($string, 1, $length-2) . $string[0];
        break;
}
echo $newStr; // on
Sverri M. Olsen
  • 13,055
  • 3
  • 36
  • 52
1

try like this:

$string="hello";
$first=$string[0]; //get first character
$last=$string[strlen($string)-1]; //get last character
$string[0] =  $last; // set last character as first
$string[strlen($string)-1] =$first;  //  set first character as last
echo $string;

OUTPUT:

oellh

live test

Awlad Liton
  • 9,366
  • 2
  • 27
  • 53
1

Use preg_replace(). Capture the first character, then the zero or more characters before the last character, then the last character. The replacement will just need to swap the position of the 3rd capture group with the 1st capture group. The 2nd group will remain unchanged, but needs to be captured so that it can be used in the replacement.

If using the . metacharacter and your string might contain newlines, then add the s pattern modifier after the ending pattern delimiter.

Code: (Demo)

$string = "hello";
echo preg_replace('/(.)(.*)(.)/', '$3$2$1', $string);
// oellh

For anyone needing multibyte support, you can use either of the following to accommodate multibyte/unicode characters and graphemes.

echo preg_replace('/(.)(.*)(.)/u', '$3$2$1', $string);

or

echo preg_replace('/(\X)(\X*)(\X)/u', '$3$2$1', $string);

Not only are these solutions concise, they are reliable even when the input string has only 1 or 2 characters total. (Demo)

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • Relating to matching any encounter-able character: [How to match any full unicode character, with modifiers etc, in regex?](https://stackoverflow.com/q/74648653/2943403) – mickmackusa May 24 '23 at 22:06
-1

str_replace's first two arguments can take arrays for multiple replacements.

3289105
  • 1
  • 2