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

I have a variable $location whose value is data,I want to match another variable $file with /$location/ making the later "/" optional,meaning match $file to /data/(later "/" is optional),how can I make the later "front slash(/)" optional?If it is present it should match,if it not present ignore

$location="data"; next if $file !~ /$location[/]

Replies are listed 'Best First'.
Re: Making the later front slash "/" optional
by davido (Cardinal) on May 03, 2011 at 07:24 UTC

    First, don't confuse things by using '/' as your "quote like characters" for the regular expression. A regexp can look like this: m//, or you can use a wide variety of other characters, such as m{} or m!!. The reason this is helpful is that if your regexp has any literal '/' in it, you end up having to escape it with a preceding backslash. This leads to the leaning-toothpicks effect: (example) m/\\|\// matches '\' or '/', and does so in a visually confusing way.

    Now that we've got that annoyance out of the way, we can use visually clear code. Your objective now is simply to make that trailing slash optional. The character inside of a regexp that means 'optional' is the question mark. So it could look like this:

    m{$location/?$}

    Now on the other hand, if the expression held in $location actually ends in a slash too, then you're going to need to prepare your regexp with a little more care. Here I'm going to examine $location to see if it ends in a slash, and if it does, append a question mark. Then I'll use that new string as my regular expression.

    my $file = 'some_filename'; my $location = 'some_filename/'; $location =~ s{/$}{/?}; # If a trailing / is found, append a ? to it. if( $file ~= m{$location$} ) { # Do your stuff }

    Dave

      Or perhaps append a trailing slash anyhow to $location and check for one or two trailing slashes?

      m{$location/{1,2}$}

      CountZero

      A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: Making the later front slash "/" optional
by Ratazong (Monsignor) on May 03, 2011 at 07:09 UTC

    next if $file =~ /^\/?$location/;
    makes the front slash optional.

    update: See the exemplary code below, which will result in OK2 OK3 OK4:

    my $s1 = "abc"; my $s2 = "/abc"; my $all = "/abc"; print "OK1\n" if $all =~ /^$s1/; print "OK2\n" if $all =~ /^$s2/; print "OK3\n" if $all =~ /^\/?$s1/; print "OK4\n" if $all =~ /^\/?$s2/;

    update 2: Thanks for the hint davido. Now that you point it out, I see that I misinterpreted front and later. @OP: please use the solution provided by davido instead!

      I could be mistaken here, but I think OP is saying "front slash" when he means "forward slash", and "later" means... "trailing." In other words, my assumption is that he wants to make the trailing forward-slash optional.


      Dave

Re: Making the later front slash "/" optional
by anonymized user 468275 (Curate) on May 03, 2011 at 09:09 UTC
    next unless ( grep { $_ eq $location; } split( '/', $file ) );

    One world, one people

Re: Making the later front slash "/" optional
by 7stud (Deacon) on May 03, 2011 at 17:34 UTC

    A question mark is a special regex character that means match the previous character 0 or 1 time:

    use strict; use warnings; use 5.010; my $location = 'data'; my @fnames = ('/data', '/data/', 'data/'); for my $fname (@fnames) { if ($fname =~ m{/ $location /?}xms ) { say $fname; } } --output:-- /data /data/

    But you can use string interpolation in your regex to make your code even clearer:

    use strict; use warnings; use 5.010; my $location = 'data'; my @fnames = ('/data', '/data/', 'data/'); my $pattern = "/ $location /?"; for my $fname (@fnames) { if ($fname =~ /$pattern/xms ) { say $fname; } } --output:-- /data /data/
    You can use the /o flag to signal to perl that the variable won't change and to compile the regex only 'o'nce. That keeps perl from recompiling the regex evertime you try a match.