#Java 8, 312 308 304 301 bytes
s->{String r="",x="([AEIOU])",y="([BGNPRST])",z="0O1I2R3E4A5S6G7T8B9P";for(int c:s.replaceAll("[NU]","").getBytes())r+=z.charAt((c=z.indexOf(c)+(c<58?1:-1))<0?0:c);return s.matches("(("+x+y+")*"+x+"?)|(("+y+x+")*"+y+"?)|([0-9]*)")?r.replaceAll(x+"(?="+x+")","$1N").replaceAll(y+"(?="+y+")","$1U"):"";}
-4 bytes by removing ^
and $
from the regex, because Java's String#matches
already validates the entire String.
-4 bytes for a bug-fix (doesn't happen often that the byte-count decreases when I fix a bug in my code.. :D)
Try it here.
s->{ // Method with String parameter and String return-type
String r="", // Result-String
x="([AEIOU])",y="([BGNPRST])", // Two temp Strings for the validation-regex
z="0O1I2R3E4A5S6G7T8B9P"; // And a temp-String for the mapping
for(int c:s.replaceAll("[NU]","").getBytes())
// Loop over the characters of the input-String excluding all 'N' and 'U'
r+=z.charAt( // Get the character from the temp-String `z`
(c=z.indexOf(c)+ // by getting the character before or after the current character
+(c<58?1:-1)) // based on whether it's a digit or not
<0?0:c); // and a 0-check to prevent errors on incorrect input like '!@#'
// End of loop (implicit / single-line body)
return s.matches("(("+x+y+")*"+x+"?)|(("+y+x+")*"+y+"?)|([0-9]*)")?
// If the input is valid
// (Only containing the vowels and consonants of `x` and `y`, without any adjacent ones. Or only containing digits)
r // Return the result
.replaceAll(x+"(?="+x+")","$1N") // after we've added 'N's if necessary
.replaceAll(y+"(?="+y+")","$1U") // and 'U's if necessary
:""; // Or return an Empty String if invalid
} // End of method