$_ = '0 1 STARTPRESERVE STARTPRESERVE 2 STOPPRESERVE STOPPRESERVE 3 4 STARTPRESERVE STARTPRESERVE 5 STOPPRESERVE STOPPRESERVE 6 7'; (my $re=$_)=~s/((STARTPRESERVE)|(STOPPRESERVE)|.)/${['(','']}[!$2]\Q$1\E${[')','']}[!$3]/gs; $re= join'|',map{quotemeta}eval{/$re/}; die $@ if $@ =~ /unmatched/; s/\s+|($re)/${[$1,' ']}[!$1]/g;