Я придумал это:
(?!.*?(DDD|EEE|FFF).*?)(?<!(DDD|EEE|FFF))(AAA|BBB|CCC)
Кажется, что работает, используя следующие тестовые случаи:
123AAA //matches
123BBB //matches
123CCC //matches
123DDD //no match
123EEE //no match
123FFF //no match
AAADDD //no match
EEEBBB //no match
Объяснение: Не совпадать, если есть "DDD","EEE" или "FFF" в любом месте строки.
Не совпадать, если перед соответствующей подстрокой было "DDD", "EEE" или "FFF".(Я не знаю, зачем это нужно. Если я пропущу это, «EEEBBB» получит совпадение, и я думаю, что это не должно. Мне нужно это выяснить.)
ОбновлениеЯ думаю, что мне нужен был отрицательный взгляд сзади, потому что я не учитывал контекст, в котором совпадение подстроки произошло в строке.
Вот версия, которая не требует отрицательного взгляда сзади:
(?!^.*?(DDD|EEE|FFF).*?$)(?:^.*?(AAA|BBB|CCC).*?$)
Кажется, работает, потому что я рассматриваю всю строку.
Еще одно обновление.(Не могу оставить это в покое.) Это немного оптимизировано:
(?!^.*?(?:DDD|EEE|FFF).*$)^.*?(AAA|BBB|CCC).*$