[Question]
  [
The program should take a string as input and reverse the consonants in it, while keeping the order of vowels. All the letters will be lowercase, so you don't have to worry about casing. Examples follow. 
1. Input: `a test case`.  
The consonants here are `t,s,t,c,s`. They should come in reversed order, i.e. `s,c,t,s,t` and inserted back into the string to the same positions where the pre-reversed characters were located: `a sect sate`.
2. Input: `well-done`. Output: `nedl-lowe`.
3. Input: `reverse the consonants`. Output: `setenne sne cohtosarvr`.
This is the code golf, the shortest solution wins.
`Y` should be considered vowel regardless of what it is and not reversed.
Anything, as well as numbers, punctuation, quotes, and other symbols (`@#$%^&*(){}[]\|/<>~-_+=``), could potentially appear in the input.
  
[Answer]
# Retina, ~~22~~ ~~21~~ ~~20~~ 17
```
O#^`[b-z-[eiouy]]
```
[Try it online!](http://retina.tryitonline.net/#code=TyNeYFtiLXotW2Vpb3V5XV0&input=cmV2ZXJzZSB0aGUgY29uc29uYW50c18kI0AmIyVeKjMyMQ)
1 byte thanks to Leaky Nun!
4 bytes thanks to Martin!
`O` means sort, and `#` means to sort by numeric value. Since none of the matched characters will ever have a numeric value, all letters have the same weight: 0. `^` means to reverse the order of the sorted values, which thanks to stable sorting means the values are reversed.
The `-[...]` means to do the setwise difference between the outer character class and this inner class. This is part of .NET and you can read more at the [MSDN](https://msdn.microsoft.com/en-us/library/20bw873z(v=vs.110).aspx#Anchor_13).
[Answer]
## Python 2, 86 bytes
```
s='';c=()
for x in input():b='{'>x not in'aeiouy'<x;s+=b*'%s'or x;c=(x,)*b+c
print s%c
```
Takes input as a string in quotes. Iterates through the input, replacing each consonant with `%s` in `s`. The tuple `c` stores the consonants encountered in reversed order. Then, string formatting replaces the `%s`'s in `s` with the consonants in `c`.
Thanks to Sp3000 for the consonant check, which saved 4 bytes over listing the consonants.
[Answer]
# [Jelly](http://github.com/DennisMitchell/jelly), ~~22~~ 20 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
Øaḟ“<1Ṛż»
e€¢œpżf¢Ṛ$
```
[Try it online!](http://jelly.tryitonline.net/#code=w5hh4bif4oCcPDHhuZrFvMK7CmXigqzCosWTcMW8ZsKi4bmaJA&input=&args=J3JldmVyc2UgdGhlIGNvbnNvbmFudHMn)
### How it works
```
Øaḟ“<1Ṛż»   Helper link. No arguments.
Øa          Yield the lowercase alphabet/
   “<1Ṛż»   Decompress that string, yielding "oui aye".
  ḟ         Filter; remove the characters from the right string from the left one.
e€¢œpżf¢Ṛ$  Main link. Argument: s (string)
  ¢         Call the helper link, yielding the string of all consonants.
e€          Test each character of s for membership.
   œp       Partition s at members/consonants.
         $  Combine the three links to the left into a monadic chain.
      f¢    Filter by presence in the consonant string.
        Ṛ   Reverse the result.
     ż      Zipwith; interleave chunks of non-consonants and reversed consonants.
```
[Answer]
# JavaScript ES6, ~~82~~ ~~81~~ ~~80~~ 78 bytes
Saved a byte thanks to each of Martin and Leaky Nun, and 2 bytes to Neil!
```
a=>a.replace(r=/(?[_aeiouy])\w/g,e=>[...a].reverse().join``.match(r)[i++],i=0)
```
## Testing
```
f=
a=>a.replace(r=/(?![aeiouy])[a-z]/g,e=>[...a].reverse().join``.match(r)[i++],i=0)
;
q.onchange=q.onkeydown=q.onkeyup=function(){
  o.innerHTML = "";
  o.appendChild(document.createTextNode(f(q.value)));
}
```
```
*{font-family:Consolas,monospace;}
```
```
<input autocomplete="off" id=q>
<div id=o></div>
```
[Answer]
# GNU sed, 73
Score includes +1 for the `-r` flag passed to sed.
```
:
s/([b-df-hj-np-tv-xz])(.*)([b-df-hj-np-tv-xz])/\u\3\2\u\1/
t
s/./\l&/g
```
[Ideone.](https://ideone.com/FYvVMy)
Repeatedly switches the first and the last lowercase consonant and converts them to upper case, until there are no more matches. Then convert the whole string back to lowercase.
[Answer]
# Python 2, 106 bytes
```
s=input()
b=[x for x in s if x in'bcdfghjklmnpqrstvwxz']*2
print''.join(x in b and b.pop()or x for x in s)
```
Expects input in `"quotes"`, which I think is allowed.
[Answer]
## Pyke, 18 bytes
```
FD~c{IK_#~c{)oR@(s
```
[Try it here!](http://pyke.catbus.co.uk/?code=FD%7Ec%7BIK_%23%7Ec%7B%29oR%40%28s&input=setenne+sne+cohtosarvr&warnings=0)
or 16 bytes with the new version:
(Change so if for returns all string output and had string input, return string instead of a list)
```
FD~c{IK_#~c{)oR@
```
[Try it here!](http://pyke.catbus.co.uk/?code=FD%7Ec%7BIK_%23%7Ec%7B%29oR%40&input=setenne+sne+cohtosarvr&warnings=0)
`~c` contains the consonants: `bcdfghjklmnpqrstvwxz`
```
F                - For i in input:
  ~c{I           -  if i in "bcdfghjklmnpqrstvwxz":
       _#~c{)    -    filter(reversed(input), <-- in "bcdfghjklmnpqrstvwxz")
             oR@ -   ^[o++]
```
[Answer]
# J, 53 bytes
```
C.~[:~.<@~.@/:~"1@(,.|.)@I.@e.&'bcdfghjklmnpqrstvwxz'
```
Maybe the not the best way but I wanted to use `C.` since this can be solved using permutations.
## Usage
```
   f =: C.~[:~.<@~.@/:~"1@(,.|.)@I.@e.&'bcdfghjklmnpqrstvwxz'
   f 'a test case'
a sect sate
   f 'well-done'
nedl-lowe
   f 'reverse the consonants'
setenne sne cohtosarvr
```
## Explanation
```
C.~[:~.<@~.@/:~"1@(,.|.)@I.@e.&'...'  Input: s
                               '...'  The list of consonants
                            e.&'...'  Generate a boolean mask where an index is true
                                      if the char at that index in s is a consonant
                         I.@          Get a list of the true indices
                  (  |.)@             Reverse that list
                  (,.  )@             Join the original and reversed list as columns
            /:~"1@                    Sort each row of that 2d list
         ~.@                          Take the distinct values in each row
       <@                             Box them
   [:~.                               Take the distinct boxes - Now represents the
                                      permutation needed to solve this in cycle notation
C.~                                   Permute s according the cycles and return
```
[Answer]
# MATL, ~~18~~ ~~22~~ 21 bytes
```
tt2Y211Y2'y'hX-m)P5M(
```
*1 byte saved thanks to @Luis*
Unfortunately the longest part of this is getting the list of consonants (`2Y211Y2'y'hX-`).
[**Try it Online!**](http://matl.tryitonline.net/#code=dDJZMjExWTIneSdoWC1tKTFNYlB3KA&input=J3dlbGwtZG9uZSc)
**Explanation**
```
            % Implicitly grab the input
tt          % Duplicate twice
2Y2         % Grab the pre-defined list of all lower-case letters
llY2        % Grab the pre-defined list of lower-case vowels (excluding 'y')
'y'h        % Add 'y' to the list of vowels
X-          % Find the set difference between these two lists (the consonants)
m           % Create a boolean array the size of the input that is true for all consonants
)           % Use this as an index to grab all consonants
P           % Reverse the order of the consonants
5M          % Get the boolean array again
(           % Re-assign the flipped consonants with the original consonant locations
            % Implicitly dislpay the result
```
[Answer]
# Perl 5 (58 + 4 = 62 bytes)
```
$_=<>;$r=qr/(?![eiouy])[b-z]/;@a=/$r/g;s/$r/pop@a/ge;print
```
+4 penalty for running with `-0777` flag, which sets Perl to slurp mode to handle newlines correctly.
Accepts input through STDIN and prints to STDOUT.
## Explanation
```
                   $_=<>;   Read the input
 $r=qr/(?![eiouy])[b-z]/;   Save the regex; we'll be using it twice
                @a=/$r/g;   Store all the consonants in an array
           s/$r/pop@a/ge;   Replace each consonant with the final value in the array and pop
                   print    Output the result
```
[Answer]
## JavaScript (ES6), 72 bytes
```
s=>s.split(/([^\W\d_aeiouy])/).map((c,i,a)=>i&1?a[a.length+~i]:c).join``
```
Splitting on `/([^\W\d_aeiouy])/` results in the consonants falling in the odd-numbered entries in the array. It then suffices to switch those entries with the equivalent entry counting back from the end of the array and join the result together.
[Answer]
# JavaScript (ES6), 57 ~~70~~
**Edit** Amazing 20% saving thx @Neil
Late to the party, but it seems all javascript people missed something
```
a=>a.replace(r=/[^\W\d_aeiouy]/g,_=>c.pop(),c=a.match(r))
```
*Test*
```
f=a=>a.replace(r=/[^\W\d_aeiouy]/g,_=>c.pop(),c=a.match(r))
function test() {
  var i=I.value
  O.textContent=f(i)
}
test()
```
```
#I { width:90% }
```
```
<input id=I oninput="test()" value="reverse the consonants."><pre id=O></pre>
```
[Answer]
# Perl 5, ~~92~~ ~~68~~ 55 bytes
Saved **37** bytes thanks to [@manatwork](https://codegolf.stackexchange.com/users/4198/manatwork)'s help. ;-)
```
$_=<>;@b=@a=/[^\Waeiou]/g;print$_~~@b?pop@a:$_ for/./g
```
A translation of [@Lynn](https://codegolf.stackexchange.com/a/83196/55531) Python solution to Perl.
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~53~~ ~~50~~ 47 bytes
*-3 bytes from @manatwork. -3 bytes from @Jordan.*
```
->s{a=s.scan r=/[^\Waeiouy_]/
s.gsub(r){a.pop}}
```
[Attempt This Online!](https://ato.pxeger.com/run?1=m72kqDSpcsEiN9ulpSVpuhY39XXtiqsTbYv1ipMT8xSKbPWj42LCE1Mz80sr42P1uYr10otLkzSKNKsT9QryC2prIdq2F5SWFCu4RStlpObk5OsolOcX5aQoKsVCZBcsgNAA)
[Answer]
# Pyth, ~~26~~ ~~25~~ ~~24~~ 23 bytes
```
~~s.i:Q++\[J-G"aeiouy"\]3\_@J~~
J-G"aeiouy"sm?@dJ@_@JQ~hZ     <-- just keeping this because of the @_@
~~J-G"aeiouy"sm?@dJ@@JQ=tZ~~
sm?@dJ-G"aeiouy"@@JQ=tZ
sm|-dJ-G"aeiouy"@@JQ=tZ
```
[Test suite.](http://pyth.herokuapp.com/?code=sm%3F%40dJ-G%22aeiouy%22%40%40JQ%3DtZ&test_suite=1&test_suite_input=%22a+test+case%22%0A%22well-done%22%0A%22reverse+the+consonants%22&debug=0)
[Answer]
# Julia, 53 bytes
```
!s=s[flipud(i)]=s[i=find(c->'}'>c∉"aeiouy"<"$c",s)]
```
This takes a [character array](http://meta.codegolf.stackexchange.com/a/2216) as input and reverses its consonants in-place. [Try it online!](http://julia.tryitonline.net/#code=IXM9c1tmbGlwdWQoaSldPXNbaT1maW5kKGMtPid9Jz5j4oiJImFlaW91eSI8IiRjIixzKV0KCmZvciBzIGluIChbImEgdGVzdCBjYXNlIi4uLl0sIFsid2VsbC1kb25lIi4uLl0sIFsicmV2ZXJzZSB0aGUgY29uc29uYW50cyIuLi5dKQogICAgIXMKICAgIHByaW50bG4oam9pbihzKSkKZW5k&input=)
*Credit goes to @Sp3000 for the lowercase consonant check.*
### How it works
`i=find(...,s)` yields all indices of **s** for which the predicate *...* returns **true** and saves them it the variable **i**.
`c->'}'>c∉"aeiouy"<"$c"` performs three tests and returns **true** if and only if all are positive.
* `'}'>c` checks if the character **c** comes before **{**.
* `"aeiou"` checks if the *string* **c** comes after **a**.
* `c∉"aeiouy"` verifies that **c** is not a vowel.
Finally, `s[i]` yields all consonants and `s[flipud(i)]=s[i]` assigns them to positions in **s** that correspond to the reversed indices in in **i**.
[Answer]
# Java, 319 305 261 188 bytes
Credit to @[Leaky Nun](https://codegolf.stackexchange.com/users/48934/leaky-nun) for helping with this :-)
```
char[]r(char[]s){int i=0,j=0,n=s.length;char[]o=new char[n];for(;i<n;i++){if((s[i]+"").matches("(?![eiouy])[b-z]")){o[j++]=s[i];s[i]=65;}}for(i=0;i<n;i++)if(s[i]==65)s[i]=o[--j];return s;}
```
Old:
```
s(String p){int i=0,j=0;char[]s=p.toCharArray(),o=p.toCharArray();for(;i<s.length;i++){if(((s[i]+"").matches("[aeiouy @#$%^&*(){}\\[\\]\\|/\\\\<>~\\-_+=`]")))continue;o[j++]=(s[i]);s[i]='A';}for(i=0;i<s.length;i++)if(s[i]=='A')s[i]=o[--j];return new String(s);}
```
Inspiration taken from [**here**](https://stackoverflow.com/a/5692490/3893016) ❤
### Ungolfed
```
String s(String p){
    int i = 0, j = 0;
    char[]s=p.toCharArray(),o=p.toCharArray();
    for (;i<s.length;i++) {
        if (((s[i]+"").matches("[aeiouy @#$%^&*(){}\\[\\]\\|/\\\\<>~\\-_+=`]"))) continue;
        o[j++] = (s[i]); // Store the consonant into o
        s[i] = 'A'; // Put a special character in its place
    }
    for (i=0;i<s.length;i++)
        if (s[i] == 'A') // If special character
            s[i] = o[--j]; // Put back the consonant in reverse order
    return new String(s);
}
```
[Answer]
# R, 120 bytes
New answer:
```
az=function(x){
y=strsplit(x, NULL)[[1]]
a=regexpr("[bc-df-hj-np-tv-z]", y)
y[a==1]=rev(y[a==1])
paste(y, collapse="")
}
```
takes a character string as x
```
az("reverse the consonants")
[1] "setenne sne cohtosarvr"
```
Old response below (110 bytes) was poor form on my part, which just reversed the consonants:
```
xrev=function(x){y=rev(strsplit(x, NULL)[[1]])
paste(y[is.na(match(y, c("a", "e","i","o","u","y")))], collapse="")}
```
[Answer]
## Python 2, ~~103~~ ~~98~~ 100 bytes
```
import re
def r(s):a=re.split("([^\W\d_aeiouy])",s);print''.join(sum(zip(a[::2],a[-2::-2]+['']),()))
```
Port of my JavaScript answer. Edit: Saved 5 bytes thanks to @Dennis♦, of which I promptly had to spend two fixing digits.
[Answer]
# [s-lang](http://dgrissom.com/s-lang/), ~~17~~ 16 bytes (non-competing)
*Saved one byte because s-lang no longer requires last argument bracket*
### [Try it online!](http://dgrissom.com/s-lang/?r[(?![aeiouy])%5Cw)
```
r[(?![aeiouy])\w
```
I started working on a string manipulation golfing language (I have been wanting to do this for a time now), and I thought this would be a fun question to work on it with.
## Explanation:
* `r` reverses the string with a given regex character matcher (if no regex argument is given, it will default to `.`)
* `[` begins the optional regex argument for `r`
* `(?![aeiouy])\w` the regex to match any consonant character excluding y (unfortunately JavaScript doesn't allow character class subtraction)
* `]` usually ends optional regex argument for `r`, but we don't need it since it is the last function and last argument
[Answer]
# APLX, 31 [bytes](http://meta.codegolf.stackexchange.com/a/9429/43319)
```
(c/t)←⌽t/⍨c←(t←⍞)∊⎕a~'aeoiuy'
t
```
`⎕a~'aeoiuy'` lowercase alphabet without vowels  
`t←⍞` store character input as *t*  
`c←(`…`)∊` store Boolean "consonant?" as *c*  
`t/⍨` extract (consonants) from *t*  
`⌽` reverse  
`(c/t)←` replace consonants with (the reversed ones)  
`t` return the modified string
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 11 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
.āžPIåÏø`Rǝ
```
I/O as a list of characters.
[Try it online](https://tio.run/##yy9OTMpM/f9f70jj0X0BnoeXHu4/vCMh6Pjc//@jlYqUdJRSgbgMSoP4xSC2ApAoAeIMqASInwzE@UCcB1UEYydC6RKweCwA) or [verify all test cases](https://tio.run/##yy9OTMpM/V9Waa@k8KhtkoKSfWXw4Qmh//WONB7dFxBxeOnh/sM7EoKOz/3vpfM/WilRoSS1uEQhObE4VUlHqTw1J0c3JT8PxC5KLUstKk5VKMlIVUjOzyvOz0vMKylWigUA).
**Explanation:**
```
.ā          # Enumerate the (implicit) input, pairing each character with its index
  žP        # Push the consonants constant (excluding 'y'): "bcdfghjklmnpqrstvwxz"
    I       # Push the input
     å      # Check for each character if it's in the consonants string
      Ï     # Keep the enumerated pairs at the truthy indices
       ø    # Zip/transpose; swapping rows/columns
        `   # Dump the list of consonants and list of indices separated to the stack
         R  # Reverse the list of indices
          ǝ # Insert the consonants at the (reversed) indices in the (implicit) input
            # (after which the result is output implicitly)
```
[Answer]
## Python 2.7, 144 bytes
```
def f(a):c='bcdfghjklmnpqrstvwxz';b=[x for x in list(a[::-1])if x in c];[b.insert(x,a[x])for x in range(len(a))if a[x]not in c];return''.join(b)
```
This first builds a reversed list of the consonants, then inserts each of the other characters back in at their original index.
Un-golfed:
```
s = 'well-done'
reverse = list(s[::-1])
consonants = [i for i in reverse if i in 'bcdfghjklmnpqrstvwxz']
for x in range(len(s)):
    if s[x] not in 'bcdfghjklmnpqrstvwxz':
        consonants.insert(x,s[x])
print(''.join(consonants))
```
<https://repl.it/C30O>
[Answer]
# Mathematica 216 bytes
```
Module[{h,v,i},v=Characters["aeiouy "];h[s_]:=SortBy[Flatten[Thread/@Transpose@{v,#[[All,1]]&/@(StringPosition[s,#]&/@v)},1],Last];i[s_,{a_,n_}]:=StringInsert[s,a,n];Fold[i,StringReverse@StringReplace[#,v->""],h@#]]&
```
[Answer]
# Haskell, ~~157~~ 131 bytes
```
k="bcdfghjklmnpqrstvwxz";f c((r:q),s)=if c`elem`k then(q,r:s)else(r:q,c:s);f c("",s)=("",c:s);g s=snd$foldr f(filter(`elem`k)s,"")s
```
**Update**
@atlasologist's solution made me realize I only need a list of the consonants instead of pairs (no need to reverse them though since I'm using right fold.)
**Ungolfed**
```
consonants = "bcdfghjklmnpqrstvwxz"
-- Combining function (right fold, improved)
f :: Char -> (String, String) -> (String, String)
f c ((r:rest), s) = if c `elem` consonants then (rest, r:s) else (r:rest, c:s)
f c ("", s) = ("", c:s)
transform :: String -> String
transform s = snd $ foldr f (filter (`elem` consonants) s, "") s
main = do
    line <- getLine
    putStrLn . transform $ line
```
---
**Old**
```
c="bcdfghjklmnpqrstvwxz";n c(a@((f,t):q),s)=if c==f then(q,t:s)else(a,c:s);n c([],s)=([],c:s);g s=let z=filter(`elem`c)s in snd$foldr n(zip (reverse z)z,"")s
```
Creates a list of pairs of consonants, then walks through the string replacing each consonant using said list.
A bit primitive, but I wanted to figure this out without looking at the answers first. :)
[Answer]
## Matlab, 67 chars
For an input `'this is a string of- stuff.'`
```
s=input('','s');si=regexp(s,'[b-df-hj-np-tv-xz]');s(si)=s(flip(si))
```
produces `s = ffit is a fgnirt os- ssuht.`
`si` is the indices of the consonants in the input string. The final statement replaces those characters with the same characters but in reverse order by indexing.
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), 81 bytes
```
-join(($a=$args|% t*y)|%{if($_-in($c=$a-match'[^\W\d_aeiouy]')){$_=$c[--$i]};$_})
```
[Try it online!](https://tio.run/##RVBdTsMwDH7vKazJJQlqLgCqxC142EYVpR4t6pIRZxtT27MXbzDwm78f@7MP8UyJOxqGBXdQw7jYj9gHrdHV6NI7TyXkx4uZyrHfaWyscOiFsnuXfafWb5vXTds46uPxslXGjNjU6NfWYr@dn7GZzTIXxYsuQKrSykEmzuAdk6qkY/IZ2GVS5i45SxrbxnAVBGoHO0jIfzrRSSIT5I7Ax8AxuJBZVaCYMoVAwOHKdDmyS6ckTgMTlDDeJiBXgPR1kL3UysXY/MCJ@DhkAR7kEcg3cIX6F7f0@WcyT3f1qpiXbw "PowerShell – Try It Online")
Less golfed:
```
$a          = $args|% toCharArray
$consonants = $a-match'[^\W\d_aeiouy]'
$result     = $a|%{if($_-in$consonants){$_=$consonants[--$i]};$_}
-join($result)
```
---
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), 88 bytes, -f
```
$i=0;-join($args|% t*y|%{if($_-match'[^\W\d_aeiouy]'){$c=,$_+$c;$_="{$i}";$i++};$_})-f$c
```
[Try it online!](https://tio.run/##RVDNboMwDL7zFBYyCwwi7TyEtLfoYd1QFMxIxZI2TttVwLOztFs3374f25@9d2fyPNA4rthDA9OKpnmq5c4Zm6PyHzxnEB4vczaZPsdWfqqgB/H6vt1su1aRccfLmygm1E2FbYm6xrZJJzRLWqMpyyXipZA96nVJkpc8gVhVLhQE4gBaMYkqIiYdgFUgUdwt5xhKds5eDZa6UY4x67/s6RSTE4SBQDvLziobWFQgmAJZS8D2qgzBsfInHzsLmCGD6TYBuQKkr33cS108HNsf2hMfxxCJh/gP5BuZYv7LSzr8NRXPd3eaLOs3 "PowerShell – Try It Online")
[Answer]
# [APL (Dyalog Extended)](https://github.com/abrudz/dyalog-apl-extended), 22 bytes
```
⌽@(('aeiou'~⍨∘⌊⎕A)∊⍨⊢)
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT9dNrShJzUtJTfn//1HPXgcNDfXE1Mz8UvW6R70rHnXMeNTT9ahvqqPmo44ukEDXIs3/aY/aJjzq7QMKe/o/6mo@tN74UdtEIC84yBlIhnh4Bv9PU1BPVChJLS5RSE4sTlXnAvLLU3OAVubnQXhFqWWpRcWpCiUZqQrJ@XnF@XmJeSXF6gA "APL (Dyalog Extended) – Try It Online")
[Answer]
# [Raku](https://raku.org/), ~~48~~ 46 bytes
```
{my$r=/<:L-[aeiouy]>/;S:g[$r]=pop @||=m:g/$r/}
```
[Try it online!](https://tio.run/##HcexCsIwFAXQX7mUYBZLNodqih/g5lhKCfWlCmlSXqIS2n57BM92FmJ3KnPGwUKXdc6Ctbo0t7oz9Arv3LfqfG@mTnCvl7Dgum16biYlWO0lmoxKDNAtVgsx7BVsYEiDRDFhNJHkEfJLztWP4P9h@hBHQnoSxuBj8ManKMsP "Perl 6 – Try It Online")
* `$r` is set to a consonant-matching regex.
* `@ ||= m:g/$r/` stores the consonants in the input string in the anonymous state array `@`, if it's empty.
* `S:g[$r] = pop ...` replaces each consonant with the consonant popped off the end of the array into which all of the consonants were stored initially.
[Answer]
# q/kdb+, 45 bytes
**Solution:**
```
{x[w]:x(|)w:(&)max x=/:.Q.a except"aeiouy";x}
```
**Explanation:**
Find indices of the consonants, and replace them with the reversed consonants:
```
{x[w]:x reverse w:where max x=/:.Q.a except "aeiouy";x} / ungolfed
{                                                   ; } / two-statement lambda
                                .Q.a except "aeiouy"    / alphabet (a..z) except vowels
                            x=/:                        / equals each-right (returns boolean lists where input is each a consonant)
                        max                             / 'or' the results together
                  where                                 / indices where results are true
                w:                                      / save in variable w
        reverse                                         / reverse this list
      x                                                 / index into input at these indices
 x[w]:                                                  / assign values to x at indices w
                                                     x  / return x
```
**Notes:**
I had 3 ways to build the consonant list, the one in the solution is slightly better than the alternatives:
* `"bcdfghjklmnpqrstvwxz"` for 22 chars (most boring)
* `.Q.a _/0 3 6 11 16 19` for 21 chars (kinda cool, drop each index)
* `.Q.a except"aeiouy"` for 19 chars (second most boring)
]