Возможно, да, очень красиво, нет. Вы можете объединить несколько проверочных утверждений, которые независимо проверяют, находится ли их слово в строке, а затем соответствуют всей строке, если ни одно из них не выдало false:
^(?=.*\bAlex\b)(?=.*\bBen\b)(?=.*\bCarol\b)(?=.*\bDavid\b).*$
См. regex demo .
Обновление в соответствии с определенным c требованием, чтобы только перечисленные слова могли присутствовать в строке:
/
^
# Make sure the line only consists of targeted words.
(?=
# First word.
(?:Alex|Ben|Carol|David)
# Three more words until the end of line.
(?:[ \t]+(?:Alex|Ben|Carol|David)){3}$
)
# Make sure all four required words are present.
(?=.*\bAlex\b)(?=.*\bBen\b)(?=.*\bCarol\b)(?=.*\bDavid\b)
# Now match the line if all assertions were true.
.*
$
/x
См. regex demo .
Разделение строки и последующее сравнение с помощью строковых функций или словарей, вероятно, было бы более производительным подходом.