Следующее регулярное выражение должно работать:
\b(?:(?:great )*granddad|dad)\b
Код R:
sentence <- "My dad, granddad and great great granddad looks alike."
str_extract_all(pattern = "\\b(?:(?:great )*granddad|dad)\\b", sentence)[[1]]
[1] "dad" "granddad" "great great granddad"
Демо
Уловка здесь состоит в том, чтобы использовать чередование, как вы уже использовали, но сначала поместить дополнительные определенные c термины. Шаблон (?:great )*granddad
сначала будет соответствовать great great granddad
, затем great granddad
(который на самом деле не встречается в вашем предложении) и, наконец, granddad
.