Отрицательный взгляд сзади подходит как нельзя лучше.
[A-GZ]{2}(?<!GB)(?<!ZZ)
Пояснение:
[A-GZ]{2}
соответствует ровно двум символам, оба из которых должны быть A-G или Z.
(?<!GB)
соответствует только в том случае, если два предыдущих сопоставленных символа не были ГБ.
(?<!ZZ)
соответствует, только если два предыдущих сопоставленных символа не были ZZ.
Отрицательный lookbehind, как и все операции lookahead и lookbehind, имеет нулевую ширину, что означает, что он не меняет положение курсора. Вот почему вы можете связать вместе два ряда подряд, как я. Мне нравится это лучше, чем |, потому что это проясняет два случая, которые не разрешены. И выполнение этого дважды должно иметь примерно тот же эффект времени выполнения, что и | оператор в единственном взгляде.