my $line = q{one }; $line =~ / ([^<]+) (?: < (two|three) > )? /x; print $1, $2; #### one two #### my $line = q{one }; #### while ($line =~ /pattern/g){ # do something with $1 and $2 } #### one [link|file.html] two [email|me@home.com] three [not a link] #### while ( $line =~ / ( [^\[]* ) (?: \[ ( (?:link|email|pdf) [^\]]* ) \] )? /xg ) { my $txt = $1; my $link = $2; if ($link){ my ($type, $address, $txt) = split(/\|/, $link); # more stuff } }