http://qs321.pair.com?node_id=1233692


in reply to processing file content as string vs array

You only have one @user_info in the whole file right? Otherwise your regex will give the wrong result: everything from the first @user_info_start to the last @user_info_end. This is because of '.*' in your regex, because * is 'greedy' it will try to match as much as possible. This means that after @user_info_start has been found, the regex engine will basically jump to the end of the file, and move backward one character at a time (this is called backtracking) until it finds @user_info_end.

To have the reverse behaviour: go forward one character at a time right after finding @user_info_start you could use (.*?), where .*? will start by matching nothing, and only consume an extra character when necessary.

That being said, I really like the idiom presented by haukex here, which is quite intuitive when you know that the .. operator is read as "FROM .. TO" so in haukex's code that would be FROM @user_info_start TO @user_info_end. One thing you can add to his code if you only have one occurence of @user_info in the whole file is an exit from the loop as soon as you have found your data:

use warnings; use strict; my @userinfo; LINE: while (<DATA>) { chomp; if ( /\@user_info_start/ ... /\@user_info_end/ ) { push @userinfo, $_; } elsif (@userinfo) { last LINE; # stop looking } } use Data::Dumper; print Dumper(\@userinfo); __DATA__ xxxxxxxxxxx xxxx*@user_info_start xxxx*@Title : Mr xxxx*@Username : xxxxx xxxx*@Filetype : txt xxxx*@Version : 0001 xxxx*@Create_Date : 20190407 xxxx*@Product : xxxx xxxx*@user_info_end xxxxxxxxxxxxxxxxxxxxxxxxxxxx