Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

How to make sure that if $mk doesnot match to anyone of @folders,then only push to an array

#!/usr/bin/perl -w use strict; use warnings; my @folders=("inc","Inc","iNc","incr","src","Src"); my $mk = "./media/common/max/tail/common.mk: $(PROJECT_ROOT)/../../ +Utils/inC"; my $folder_match; my @folder_match; foreach $folder_match(@folders) { if($mk !~ /^\/\Q$folder_match\E$/i)# if $mk doesnot match to anyone + of @folders,then only push { push @folder_match ,$mk; } } print "@folder_match\n";

Replies are listed 'Best First'.
Re: Pushing to an array
by kennethk (Abbot) on Mar 23, 2011 at 20:21 UTC
    This simplest change you could make to your code to achieve your goal would be to add a flag:

    my $found = 0; foreach $folder_match(@folders) { if($mk =~ /^\/\Q$folder_match\E$/i) {# if $mk doesnot match to any +one of @folders,then only push $found = 1; } } if (not $found) { push @folder_match ,$mk; }

    If I were given this task, I would use grep instead, though you could also accomplish this with help from List::MoreUtils.

      For both the below inputs $found is "0",any idea why?Ideally for "inc" $found should match

      $mk =./media/common/max/tail/common.mk: $(PROJECT_ROOT)/../../Utils/inc -->$found should be 1

      $mk= ./media/common/max/tail/common.mk: $(PROJECT_ROOT)/../../Utils/inC -->$found should be 0

      #!/usr/bin/perl -w use strict; use warnings; my @folders=("inc","Inc","iNc","incr","src","Src"); my $mk = "./media/common/max/tail/common.mk: $(PROJECT_ROOT)/../../ +Utils/inc"; my $folder_match; my @folder_match; my $found = 0; foreach $folder_match(@folders) { if($mk =~ /^\/\Q$folder_match\E$/i) {# if $mk doesnot match to any+one of @folders,then only push $found = 1; } } print "\nFOUND:$found\n"; if (not $found) { push @folder_match ,$mk; } print "@folder_match\n";
        You issue is that $mk does not contain the string ./media/common/max/tail/common.mk:    $(PROJECT_ROOT)/../../Utils/inc as you expect. Variables interpolate in double quotes (see Quote and Quote like Operators), so you are interpolating the special variable $( in your string. You can resolve your issue by either escaping the $ character with a back slash

        my $mk = "./media/common/max/tail/common.mk:    \$(PROJECT_ROOT)/../../Utils/inc";

        or you can swap to string delimiters that do not interpolate, like single quotes

        my $mk = './media/common/max/tail/common.mk:    $(PROJECT_ROOT)/../../Utils/inc';

Re: Pushing to an array
by wind (Priest) on Mar 23, 2011 at 20:29 UTC
    Turn the list of folders into a single regex, then do your test. Add boundary conditions to the regex as required.
    #!/usr/bin/perl -w use strict; use warnings; my @folders = qw(inc Inc iNc incr src Src); my $folders_re = join '|', map {quotemeta} @folders; my $mk = "./media/common/max/tail/common.mk: $(PROJECT_ROOT)/../../ +Utils/inC"; my @folder_match; if ($mk !~ /$folders_re/i) { push @folder_match ,$mk; } print "@folder_match\n";
Re: Pushing to an array
by locked_user sundialsvc4 (Abbot) on Mar 23, 2011 at 20:38 UTC

    I would quite frankly suggest that you look for the simplest possible way to do this ... do it ... and then be done with it.   Unless you have a truly extraordinary amount of data (in which case you probably would be using an SQL table anyway), “the quickest and easiest (for you, for now) way to do” such a task, is the way to do it.   Simply make the intention of the code well-documented and clear, and test it thoroughly.