[Question]
  [
Inspired by [this challenge](https://codegolf.stackexchange.com/questions/109117/unscramble-those-case-very-sensitive-strings?atw=1) (or, more specifically, by misreading it), I've come up with the following challenge:
Given an input string S, reverse the order of all uppercase characters, and all lowercase characters. Leave all non-letter characters in place. For instance:
[![Hello, World!](https://i.stack.imgur.com/IirFB.jpg)](https://i.stack.imgur.com/IirFB.jpg)
Note that the uppercase `W` (the first uppercase letter) was replaced with `H` (the last). Same goes for the lowercase letters: 'd' (the first) is swapped with `e` (the last), `l` (second) gets replaced with `l` (pen-ultimate) ... All the non-letter characters are left in place.
## Input
* Input is a string with only ASCII characters in the range 32-126.
* Input is guaranteed to be at least 1 character long, and won't exceed your language's limit.
## Output
* That same string, with the characters swapped as described.
## Additional rules
* [Standard loopholes](https://codegolf.meta.stackexchange.com/questions/1061/loopholes-that-are-forbidden-by-default) are forbidden
* Answer must be a full program or a function, not a snippet or a REPL-entry.
* [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), shortest answer in bytes wins.
## Test cases
```
A
A
Ok
Ok
OK
KO
Hello, World!
Wdlro, Holle!
0123456789
0123456789
The quick brown Fox jumps over the lazy doge
Feg odyza lehtr Tev ospmu jxon wor bkci uqeh
odd
ddo
racecar
racecar
EtOn Em OsN R AaToNsIsIhT!!1!
ThIs Is NoT A RaNsOmEnOtE!!1!
```
  
[Answer]
# [Retina](https://github.com/m-ender/retina), 19 bytes
Retina doesn't have a direct way to reverse a string, but we can do it by exploiting the sorting stage:
```
O^#`[a-z]
O^#`[A-Z]
```
Sort (`O`), reading them as numbers (`#`), and then reverse the ordering (`^`), of all the strings matching the given regex (lowercase letters for the first line, and uppercase letters for the second).
This works because when we try to read strings without numeric characters as numbers they get treated as `0`, so all the characters have the same value for sorting. Since sorting is stable they are left in the same order, and reversing them returns the original string reversed.
[Try it online!](https://tio.run/nexus/retina#HcnLCoJAFADQ/f2KO0TQIiF7t3Rh5caBGAgKxckZshq9NaM9/HmLdgdOf7DJOp72sqP02gT@CrxD0nUBbLUxNMQ9WaMYwsgfT6az@WK5AlFofDSX/IYnS68K1/TGa1PeHdJTW6x/bWT7QUVnDaQUWJnrXFoIa15hWCJ3Me4wkIJiF7moEIz57As "Retina – TIO Nexus")
[Answer]
# [Perl](https://www.perl.org/), 45 bytes
44 bytes of code + `-p` flag.
```
for$c(u,l){@T=/\p{L$c}/g;s/\p{L$c}/pop@T/ge}
```
[Try it online!](https://tio.run/nexus/perl#U1YsSC3KUdAt@J@WX6SSrFGqk6NZ7RBiqx9TUO2jklyrn25dDGcX5Bc4hOinp9b@/@9a4p@n4Jqr4F/spxCk4JgYku9X7FnsmRGiqGioCAA "Perl – TIO Nexus")
Unicode characters classes `\p{Lu}` and `\p{Ll}` matches respectively uppercase and lowercase letters.  
So `/\p{L$c}/` will return the list of all upper (or lower) case letters (and store it inside `@T`).  
And then, the regex `s/\p{$c}/pop@T/ge` will replace each (upper, then lower case) letter by the last letter of `@T` while removing it from `@T`.
[Answer]
## JavaScript (ES6), ~~74~~ ~~73~~ ~~71~~ 70 bytes
```
f=
s=>(g=r=>s=s.replace(r,_=>a.pop(),a=s.match(r)))(/[A-Z]/g,g(/[a-z]/g))
```
```
<input oninput=o.textContent=f(this.value)><pre id=o>
```
Edit: Saved 1 byte thanks to @Arnauld.
[Answer]
# [MATL](https://esolangs.org/wiki/MATL), 14 bytes
```
2:"t@Y2myy)Pw(
```
[**Try it at MATL Online**](https://matl.io/?code=2%3A%22t%40Y2myy%29Pw%28&inputs=%27Hello+World%21%27&version=19.7.4)
**Explanation**
```
        % Impicitly grab input as a string
2:      % Push the array [1, 2] to the stack
"       % For each value in this array
  t     % Duplicate the top element of the stack (S)
  @     % Get the current loop index
  Y2    % Load the predefined literal 1Y2 ('ABC...Z') on the first loop
        % and the predefined literal 2Y2 ('abc...z') on the second loop (M)
  m     % Create a logical array the length of S that is TRUE when a character is in the
        % array M and FALSE otherwise (B)
  yy    % Make a copy of both S and B
  )     % Grab just the letters of S that were in M using B as an index
  P     % Reverse this array
  w     % Flip the top two stack elements
  (     % Assign them back into the string
        % Implicit end of for loop and implicit display
```
[Answer]
## JavaScript (ES6), 92 bytes
```
s=>(F=(r,s)=>s.replace(r,([x],a,y)=>y+F(r,a)+x))(/[a-z](.*)([a-z])/,F(/[A-Z](.*)([A-Z])/,s))
```
There has *got* to be a way to take advantage of the similarity between the regexes...
### Test snippet
```
let f =
s=>(F=(r,s)=>s.replace(r,([x],a,y)=>y+F(r,a)+x))(/[a-z](.*)([a-z])/,F(/[A-Z](.*)([A-Z])/,s))
```
```
<input style="width:500px" value="Wdlro, Holle!" oninput="O.value=f(this.value)"><br>
<input style="width:500px" value="Hello, World!" id=O disabled>
```
[Answer]
# [Perl 6](http://perl6.org/), ~~75~~ 69 bytes
```
{my @a=.comb;@(grep $_,@a).&{@$_=[R,] $_} for /<:Lu>/,/<:Ll>/;[~] @a}
```
### How it works
1. `my @a=.comb;`  
Split the string into characters, and store them in an array.
2. `for /<:Lu>/,/<:Ll>/`  
For two regexes matching upper and lower-case letters, respectively...
	* `@(grep $_,@a)`  
	
	Get a slice of all array entries matching the regex.
	* `.&{@$_=[R,] $_}`  
	
	Assign the reverse of the slice to itself.
3. `[~] @a`  
Concatenate the modified array to form a string again, and return it.
---
*-6 bytes by stealing the idea to use Unicode classes instead of character ranges, from @Dada's solution.*
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 14 bytes
```
nŒlT,Ṛ$yJịŒsµ⁺
```
[Try it online!](https://tio.run/nexus/jelly#@593dFJOiM7DnbNUKr0e7u4@Oqn40NZHjbv@P9y95XD7o6Y1kf//O3L5Z3P5e3N5pObk5OsohOcX5aQochkYGhmbmJqZW1hyhWSkKhSWZiZnKyQV5ZfnKbjlVyhkleYWFCvkl6UWKZQApXMSqyoVUvLTU7nyU1K4ihKTU5MTi7hcS/zzFFxzFfyL/RSCFBwTQ/L9ij2LPTNCFBUNFQE "Jelly – TIO Nexus")
### How it works
```
nŒlT,Ṛ$yJịŒsµ⁺  Main link. Argument: s (string)
 Œl             Convert to lowercase.
n               Test for inequality.
   T            Truth; yield all indices of 1's.
    ,Ṛ$         Pair with its reverse. Yields [A, B] (pair of lists).
        J       Indices; yield I := [1, ..., len(s)].
       y        Translate; replace the integers of I that occur in A with the
                corresponding integers in B.
          Œs    Swapcase; yield s with swapped case.
         ị      Use the translated index list to index into s with swapped case.
            µ   Combine all links to the left into a chain.
             ⁺   Duplicate the chain, executing it twice.
```
[Answer]
# [Bash](https://www.gnu.org/software/bash/) + Unix utilities, ~~122~~ 121 bytes
```
f()(p=[^$1*
v="\)\([$1\)\("
for((n=99;n;n--)){
q="$q;s/^\($p$v.*$v$p\)$/\1\4\3\2\5/"
p=[^$1*[$1$p
}
sed $q)
f a-z]|f A-Z]
```
[Try it online!](https://tio.run/nexus/bash#Lcy7DoIwFIDhvU9x0pyhJakELwMhDC4@gZMcSFCKd1pAqqI@O2Li9A9/8g2lkMLGSYaBx1zMSZJIMPiFs9I0QlRxGEZVVCkl5YvVMcc6av2MBFp0Ew8dWpLoU0BzmtGUFj5nf3CE0LIPa3UBWEtWQq769F3CUm3SYVgfNNTdcXeGbWPuFazMA07d1bZgnG7gNu5L3j@hMHv9BQ "Bash – TIO Nexus")
Not really very short; maybe someone can golf it further.
Input on stdin, output on stdout.
This will work correctly on inputs of less than 200 characters. 
(Actually it correctly handles any string with fewer than 200 lower-case letters and fewer than 200 upper-case letters.)
If you increase the 99 in the code to 102 (at the cost of one additional byte), it will handle strings up to 205 characters.
However, you can't increase the 99 in the code beyond 102 since you'll then exceed sed's maximum argument length.
Here's a version without any particular input size limitation, but the count is a little longer, 137 bytes. (This longer version writes to an auxiliary file named t.)
```
f()(p=[^$1*
v="\)\([$1\)\("
for((n=`wc -c<t`;n;n--)){
sed -i "s/^\($p$v.*$v$p\)$/\1\4\3\2\5/" t
p=[^$1*[$1$p
})
cat>t
f a-z]
f A-Z]
cat t
```
Test runs:
```
for x in A Ok OK 'Hello, World!' 0123456789 'The quick brown Fox jumps over the lazy doge' odd racecar 'EtOn Em OsN R AaToNsIsIhT!!1!'
  do
    echo "$x"
    ./swapping3 <<<"$x"
    echo
  done
A
A
Ok
Ok
OK
KO
Hello, World!
Wdlro, Holle!
0123456789
0123456789
The quick brown Fox jumps over the lazy doge
Feg odyza lehtr Tev ospmu jxon wor bkci uqeh
odd
ddo
racecar
racecar
EtOn Em OsN R AaToNsIsIhT!!1!
ThIs Is NoT A RaNsOmEnOtE!!1!
```
[Answer]
# [Python 2](https://docs.python.org/2/), 115 bytes
```
s=input();u=str.isupper
exec"r='';i=0\nfor c in s:r+=c[u(c):]or filter(u,s)[~i];i+=u(c)\ns=r.swapcase();"*2
print s
```
[Try it online!](https://tio.run/nexus/python2#FY3NbsIwEITveYpNLk4AIaA/FCIfOFAVVSJSFakH4GAcU1yC7e7ahfbQV0/N5dPOzmhGXZUEzLKsI66NCz4vysDJ41BTcE5homIiQ85Yqfloaw4WQYI2QHPsc7kJuSzmu/g86NYrzMOAis2f3pW6z2/e1hDHIV2Ek4JUbM96k8ShNh6oi7u9WccWLGHV6YbXiBfVtnYA7xbbJo16NJ7c3T88Tp9mUdRHBV9ByxPs0V4MPNsrfIazI7DfCsFHuxW/P9DYDxXjtmkiUUglBcZr6SsDyzNUtIY3WIjarmlFq2OdpuOU/QM "Python 2 – TIO Nexus")
[Answer]
# [Java (OpenJDK 8)](http://openjdk.java.net/), 271 bytes
```
s->new String(new Error(){char[]o=s.toCharArray();char c;int b;{while(b++<2)for(int l=0,r=o.length;l<r;l++){for(--r;r>l&&f(r);r--);for(;l<r&&f(l);l++);if(l<r){o[l]=o[r];o[r]=c;}}}boolean f(int i){c=o[i];return b>1?!Character.isUpperCase(c):!Character.isLowerCase(c);}}.o)
```
[Try it online!](https://tio.run/nexus/java-openjdk#VVCxasMwEN39FcoSJFyLtmMUp5QQ6NBOoXQwHmRFiVXOljnJCcH4213JSQu9QTree3f3eKbpLHryLc@S994Af0WUVyeSpOsrMIookM6RD2laMiQJCXUnnJc@fGdrDqQJNN17NO2pKInEk2NBTe51W8mdRy0bOrO8kR2dXLZp9YXcBmlsd4gWKRtULbEobe64t9vQzysoExEnSpjWk0oMl9qAplWarp/ZMcxFGPLHB8wtB92efC1gjQLSlA2RzzIUuIHl8kiRCcwyJiIcRREDNkuFCe0a2WALKHNbYCnikysxjmNlLWjZkuN8zASnQWFKgdr32JJq8/SyiIal8hq5cZ9dp3ErnaaKrf4x7/byx4TN3LLpNzDGg62dVDXdX53XDbe9X626kJKHlok52DEZp@lNA1jyZREOix8 "Java (OpenJDK 8) – TIO Nexus")
[Answer]
# [R](https://www.r-project.org/), 107 bytes
```
u=utf8ToInt(scan(,''));for(i in c(65,97)){l=which(u%in%i:(i+25));u[l]=u[rev(l)]};cat(intToUtf8(u,T),sep="")
```
Adapted from my response to the linked challenge. This is considerably easier than just swapping pairs. I wonder if I could get sub 100 with some golfs...
[Try it online!](https://tio.run/##Dcy7DsIgFADQX7khMb1EJpP6alhN3HFqOlSkgiJUCq2P@O3Y/eSEnBNPsdsKf3QRB9k6ZEVBadX5gAaMA4nrku02lH4tn7SRGtPCuIXZo1muylmm2jY81UGNaGnzq2Qb0bgo/Gl@MTFB2aB6TgjN5KCu4C/vTwtW6RhAqBH80D8S3F7eweQDnO/SQHoqTfIf "R – Try It Online")
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 19 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
2FÐlø€Ë≠āsƶ0KÂ‡<è.š
```
I/O as a list of characters.  
Based on [my 05AB1E answer in the related challenge](https://codegolf.stackexchange.com/a/206284/52210).
[Try it online](https://tio.run/##yy9OTMpM/f/fyO3whJzDOx41rTnc/ahzwZHG4mPbDLwPNz1qWGhzeIXe0YX//0cruSrpKJUAsT8Q5wGxAhCDxHKhbJB4MRD7QflBUNoRiBOBOASI86HyIHWeSHQGVF4Rig3BdCwA) or [verify all test cases](https://tio.run/##yy9OTMpM/V9TpuSZV1BaYqWgoGRfqcOl5F9aAuYCecH/jdwOT8g5vONR05rD3Y86FxxpLD62zcD7cNOjhoU2h1foHV34v9ZL59A2@/@OXP7ZXP7eXB6pOTn5Ogrh@UU5KYpcBoZGxiamZuYWllwhGakKhaWZydkKSUX55XkKbvkVClmluQXFCvllqUUKJUDpnMSqSoWU/PRUrvyUFK6ixOTU5MQiLtcS/zwF11wF/2I/hSAFx8SQfL9iz2LPjBBFRUPF/7q6efm6II0A).
**Explanation:**
```
2F            # Loop 2 times:
  Ð           #  Triplicate the current character-list
              #  (which will use the implicit input-list in the first iteration)
   l          #  Lowercase all letters of the top copy
    ø         #  Zip/transpose the top two lists; pairing them together, and swapping
              #  rows/columns
     €Ë≠      #  Check for each pair whether they're NOT the same
              #  (so uppercase characters that have now become lowercase)
  ā           #  Push a list in the range [1, length] (without popping)
   s          #  Swap so the mapped list is at the top again
    ƶ         #  Multiply each 1/0 by its 1-based index
     0K       #  Remove all 0s
       Â      #  Bifurcate it (short for Duplicate & Reverse copy)
        ‡     #  Transliterate the indices with the reversed indices in [1, length]
         <    #  Decrease each by 1 (because 05AB1E uses 0-based indexing)
          è   #  Index them into the current character-list
           .š #  And swap all cases (lowercase to uppercase, and vice-versa)
              # (after the loop, the resulting character-list is output implicitly)
```
]