#!/usr/bin/perl use strict; use warnings; while () { chomp; print "$_: ", /^(?{ %choices = map {;"\Q$_" => 1} qw !X Y Z! }) (?: (?!)? # Will never match, but keeps perl from whining. ((??{ keys %choices ? join "|" => keys %choices : "(?!)" })) (?{ delete $choices {$1} }))+ (?(?{ keys %choices })(?!)|)$/x ? "ok\n" : "not ok\n"; } __DATA__ XYZ ZYX ZXY XY ZYYX ABC XYZ: ok ZYX: ok ZXY: ok XY: not ok ZYYX: not ok ABC: not ok