One way to do this is to pass it through two regular expressions making sure they both match (assuming you want to use regular expressions at all, see below for an alternative):
^b*(ab*ab*)*$
^a*ba*(ba*ba*)*$
Anything else (and, in fact, even that) is most likely just an attempt to be clever, one that's generally a massive failure.
The first regular expression ensures there are an even number of a
with b
anywhere in the mix (before, after and in between).
The second is similar but ensures that there's an odd number of b
by virtue of the starting a*ba*
.
A far better way to do it is to ignore regular expressions altogether and simply run through the string as follows:
def isValid(s):
set evenA to true
set oddB to false
for c as each character in s:
if c is 'a':
set evenA to not evenA
else if c is 'b':
set oddB to not oddB
else:
return false
return evenA and oddB
Though regular expressions are a wonderful tool, they're not suited for everything and they become far less useful as their readability and maintainability degrades.
For what it's worth, a single-regex answer is:
(aa|bb|(ab|ba)(aa|bb)*(ba|ab))*(b|(ab|ba)(bb|aa)*a)
but, if I caught anyone on my team actually using a monstrosity like that, they'd be sent back to do it again.
This comes from a paper by one Greg Bacon. See here for the actual inner workings.