Я бы сделал следующее:
- регулярное выражение четное соответствует символу a , затем последовательность b , затем символ a снова, затем другая последовательность b , такая, что есть четное число b 's:
даже -> ( a ( bb ) * a ( bb ) * | a b ( bb ) * a b ( bb ) *)
- регулярное выражение нечетное делает то же самое с нечетным общим числом b s:
нечетное -> ( a b ( bb ) * a ( bb ) * | a ( bb ) * a b ( bb ) *)
Строка четного числа a и нечетное число b либо:
- начинается с нечетного числа b и являетсяс последующим четным числом нечетных образцов средиst четные паттерны;
- или начинаются с четного числа b 's, после чего следует нечетное число нечетных паттернов среди четные узоры.
Обратите внимание, что четные не имеют никакого влияния на четность / нечетность a / b в строке.
регулярное выражение -> (
b ( bb ) * даже * ( нечетное четное * нечетное ) * четное *
|
( bb ) * четный * нечетный четный * ( нечетный четный * нечетный ) * четный *
)
Конечно, каждый случай может заменить четный и нечетное в последнем регулярном выражении для получения одного регулярного выражения.
Легко видеть, что строка, удовлетворяющая этому регулярному выражению, действительно будет иметь четное число a 's (как символ a встречается только в четных и нечетных подрешетках, каждый из которых использует ровно два a ) и нечетноечисло b 's (первый случай: 1 b + четное число b ' s + четное число нечетное ; второй случай: четное число b 's + нечетное число odd ).
Строка с четным числом a ' s инечетное число b будет удовлетворять этому регулярному выражению, так как оно начинается с нуля или более b , затем следует [один a , ноль или более б s, еще один a и ноль или более b 's, ноль или более раз.