my( $state, $prev, @match )= ( "no foo" ); foreach my $tok ( split /(foo|tarbar|bar)/, $string ) { if( "foo" eq $tok ) { $state= "foo"; next; } elsif( "tarbar" eq $tok ) { if( "other" eq $state ) { push @match, $prev; # and/or do other stuff here } } elsif( "bar" ne $tok && "foo" eq $state ) { $prev= $tok; $state= "other"; next; } $state= "no foo"; }