# requires the (?{...}) structure use re 'eval'; while ($HTML =~ m{ \G ( $open (?{ $STATE = 'open' }) | $close (?{ $STATE = 'close' }) | $comment (?{ $STATE = 'comment' }) | [^<]+ (?{ $STATE = 'TEXT' }) ) }xg) { # do something with $1 and $STATE }