AFAIK, это не может быть сделано с помощью простого регулярного выражения (в частности, гарантируя, что буква появляется только в максимуме два раза. Вы могли бы сделать несколько выражений, таких как
[^a]*(a[^a]*(a[^a]*))
[^b]*(b[^b]*(b[^b]*))
....
, а также (сопоставление означает, что проверка не пройдена):
[^a]*aa[^a]*
[^b]*bb[^b]*
но, очевидно, это не очень хорошая идея.
Условие, что символы не повторяются вместе, возможно, можно обработать с помощью групп захвата, но я почти уверен, что другой нельзя проверить с помощью регулярного выражения.
Кстати ... почему одержимость регулярным выражением? Программирование этих проверок тривиально, регулярные выражения полезны в ряде случаев, но не каждая проверка может быть выполнена с помощью регулярных выражений.