my ($line_in) = "\n \n\n"; my @ss = $line_in =~ /<(?=[^>]*stylesheet).*?href *= *"*([^">]+)"/gis; print "$_\n" for @ss; Prints: perl1.css //www.perl.org/css/perl1.css /css/perl.css perl1.css #### # I added print lines so you can see your own handiwork. And # comments you can learn from. Nothing else is changed. #!/usr/bin/perl -w use strict; my @ss = getItemsFromFile(); print "-----\n"; foreach my $s (@ss) { print "$s\n"; } sub getItemsFromFile { local $/=undef; my ($file_in) = "\n \n\n"; # Print the data so we can compare as we go along. print "0: $file_in"; my @allItems=(); # WHILE you are able to match everything before and after "stylesheet"... # which will match the entire file... # which means this will only work once... # which means you don't need a loop here. while ( $file_in =~ m{(.*stylesheet.*)}igs ) { # Copy the entire file to $line. my $line = $1; print "1: $line"; # Remove whitespace between tags, including newlines. $line =~ s/>\s+\\n\s+\\n]/ig ) # By the way, you don't need to set up a character class for one # character. And the way you've set it up # # while ( $line =~ /stylesheet/ig ) { } # # would work just fine. { # Carve off one tag... my $line1 = $1; print "3: $line1\n"; # The code below, or something close to it, could match on the # whole file, saving you the steps you've done so far. It works # here because there can only be one tag on instance of $line1. if ( $line1 =~ m/(href *= *['"])([^'"]+)['"]/ ) { push(@allItems, $2); } } } return @allItems; } Prints: 0: 1: 2: 3: ?xml-stylesheet href="perl1.css" type="text/css"? 3: link href="//www.perl.org/css/perl1.css" rel="stylesheet" 3: link href="/css/perl.css" rel="stylesheet" 3: ?xml-stylesheet href="perl1.css" type="text/css"? ----- perl1.css //www.perl.org/css/perl1.css /css/perl.css perl1.css