简体   繁体   中英

How can I swap the values of two different characters in a string with PHP? A becomes B, B becomes A

I have a string in PHP. I want to swap a certain character with the value from another character. If I do it my way, A becoming B will replace A with B but the already existing B values will remain the same. When I try to swap B into A, there are, of course, values that were not originally swapped, because they were already there.

I tried this code.

$hex = "long_hex_string_not_included_here";
$hex = str_replace($a,$b,$hex);
//using this later will produced unwanted extra swaps
$hex = str_replace($b,$a,$hex);

I am looking for a function to swap these values.

Just use strtr . It's what it was designed for:

$string = "abcbca";
echo strtr($string, array('a' => 'b', 'b' => 'a'));

Output:

bacacb

The key functionality that helps here is that when strtr is called in the two argument form:

Once a substring has been replaced, its new value will not be searched again.

This is what stops the a that was replaced by b then being replaced by a again.

Demo on 3v4l.org

We could just try to substitute some third intermediate value for B , then replace all A to B , and then replace the marker back to A . But this always leaves open the possibility that the marker character might already appears somewhere in the string.

A safer approach is to covert the input string into an array of characters, and then walk down the array simply checking each index for A or B , and swapping accordingly.

$input = "AzzzzB";
echo $input ."\n";
$arr = str_split($input);

for ($i=0; $i < count($arr); $i++) {
    if ($arr[$i] == 'A') {
        $arr[$i] = 'B';
    }
    else if ($arr[$i] == 'B') {
        $arr[$i] = 'A';
    }
}
$output = implode('', $arr);
echo $ouput;

AzzzzB
BzzzzA

Note also that this approach is efficient, and only requires walking down the input string once.

Use a Temp value (which doesnt occur in your string. Could be anything):

$temp = "_";
$a = "a";
$b = "b";
$hex = "abcdabcd";
$hex = str_replace($a,    $temp, $hex); // "_bcd_bcd"
$hex = str_replace($b,    $a,    $hex); // "_acd_acd"
$hex = str_replace($temp, $a,    $hex); // "bacdbacd"

// Or, alternativly a bit shorter:
$temp = "_";
$a = "a";
$b = "b";
$hex = str_replace([$a, $b, $temp], [$temp, $a, $b] $hex);

Another way could be to str_split the string and use array_map test per character. If a , return b and vice versa. Else return the original value.

$hex = "abba test baab";
$hex = array_map(function ($x) {
    return ($x === 'a') ? 'b' : (($x === 'b') ? 'a' : $x);
}, str_split($hex));

echo implode('', $hex);

Result

baab test abba

Demo

My solution works for a substrings. The code is not clear but I want to show you a way of thinking.

$html = "dasdfdasdff";
$firstLetter = "d";
$secondLetter = "a";
$firstLetterPositions = array();
$secondLetterPositions = array();

$lastPos = 0;
while (($lastPos = strpos($html, $firstLetter, $lastPos))!== false) {
    $firstLetterPositions[] = $lastPos;
    $lastPos = $lastPos + strlen($firstLetter);
}

$lastPos = 0;
while (($lastPos = strpos($html, $secondLetter, $lastPos))!== false) {
    $secondLetterPositions[] = $lastPos;
    $lastPos = $lastPos + strlen($secondLetter);
}

for ($i = 0; $i < count($firstLetterPositions); $i++) {
    $html = substr_replace($html, $secondLetter, $firstLetterPositions[$i], count($firstLetterPositions[$i]));
}

for ($i = 0; $i < count($secondLetterPositions); $i++) {
    $html = substr_replace($html, $firstLetter, $secondLetterPositions[$i], count($secondLetterPositions[$i]));
}
var_dump($html);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM