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

Perl monks, I ask your wise advice. In this line of code, I want to match for example any string that has /data or /tmp in it, yet this does not seem to be working after my efforts and mild frustration. Any ideas? thank you!
<snip> elsif ( $fs =~ /^(?i)\/data\w+$/ || /^(?i)\/tmp\w+$/ ) { print "YIKES, my mother-in-law is here\n"; } ### I also tried $fs =~ /^(\/data\w+|\/tmp\w+)$/i ) ###

Replies are listed 'Best First'.
Re: YAREGEX for all
by toolic (Bishop) on Apr 22, 2008 at 20:15 UTC
    How about:
    if ($fs =~ /^(?i)\/data\w+$/ || $fs =~ /^(?i)\/tmp\w+$/ ) {

    The difference is the $fs after the ||. Your code compares the 2nd regex against $_.

    If that doesn't do it, please show some examples of values of $fs.

    Update: Here is a small example:

    #!/usr/bin/env perl use warnings; use strict; while (my $fs = <DATA>) { if ($fs =~ /^(?i)\/data\w+$/ || $fs =~ /^(?i)\/tmp\w+$/ ) { print "match: $fs"; } } __DATA__ junk /tmp /tmpfoo /data /data2 /data again junk2

    This prints:

    match: /tmpfoo match: /data2
      yes I tried that just after I posted....too funny! thanks! Ok but now my question is, is | more efficient that ||?

        Sometimes, but if these are file paths and you're doing IO, you're not going to see any time difference at all in your program. Consider using the most maintainable code in this case.

        | and || are different operators. See perlop.
Re: YAREGEX for all
by johngg (Canon) on Apr 22, 2008 at 20:38 UTC
    Do the alternation inside the regex and choose a different regex delimiter when matching *nix paths. Also consider whether the character class \w is going to match if $fs has more slashes, eg /tmp/transient.dat, or there are spaces, eg /data/New Folder. If you really are only interested in, say, /data and not /data_files then look for slash or end of string immediately following.

    elsif ( $fs =~ m{(?i)^/(?:data|tmp)(?:/|\z)} ) { ... }

    I hope this is useful.

    Cheers,

    JohnGG

Re: YAREGEX for all
by webfiend (Vicar) on Apr 22, 2008 at 20:44 UTC

    Try m{^/(?:data|tmp)\w+$}i. It's arguably easier to read and requires that you only look at a single regular expression. And let's face it, the fewer expressions we have to revisit and edit, the happier we are.

    I suspect that this won't quite be your final solution either, though. My hunch is that you are looking at filepaths, and I know that the \w+ requirement is going to fail as soon as a directory separator is found. But I could easily be wrong about what you are looking for.

    Update: And if you are concerned about efficiency, then compile your regex:

    my $pattern = qr{^/(?:data|tmp)\w+$}i; # ... elsif ( $fs =~ $pattern ) { print "YIKES, my mother-in-law is here\n"; }
Re: YAREGEX for all
by FunkyMonk (Bishop) on Apr 22, 2008 at 20:49 UTC
    I want to match for example any string that has /data or /tmp in it
    "In it" or "starts with"?

    Your code, and all the replies so far have used "starts with". If you really meant "in it" you need to drop the '^'s from any of the fine examples given so far


    Unless I state otherwise, my code all runs with strict and warnings