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

Why is the below regex failing for the below input ?

\amss\products\76xx\wconnect\bthost\brew\statext\src\aeebtextag.c-3657 +2;FILE.flf;//source/wconnect/bthost/brew/statext/rel/00.00.26/src/AEE +BTExtAG.c - LABEL : 1 OUTPUT:-AEEBTExtAG.c(just the file name) (my $file_name) = $line =~ /;\/[^\/](.*)\s-\s/;

Replies are listed 'Best First'.
Re: Regex failing
by Corion (Patriarch) on Feb 03, 2011 at 10:10 UTC

    When debugging regular expressions (and the text they should match against), I find a good technique to chop off elements from the regex until it matches:

    my $line = 'amss\products\76xx\wconnect\bthost\brew\statext\src\aeebte +xtag.c-36572;FILE.flf;//source/wconnect/bthost/brew/statext/rel/00.00 +.26/src/AEEBTExtAG.c - LABEL : 1'; print "Has ;/" if ($line =~ /;\//); print "Has ;\/[^\/]" if ($line =~ /;\/[^\/]/); print "Has ;\/[^\/](.*)\s-\s" if ($line =~ /;\/[^\/](.*)\s-\s/); (my $file_name) = $line =~ /;\/[^\/](.*)\s-\s/; print $file_name;

    That way you can easily see in your program where the matching stops. You could also use re 'debug', or output messages when the regular expression engine backtracks, but I found it always easier to manually create the relevant steps to output where my match progresses.

      Along similar lines, using the debugger (just run perl -de 0) is a good way to "prototype" your regexen. Set $_ to your target string and then just plug away building up x m{foo}, x m{fo(x|obar)}, ... until you get something that works.

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

Re: Regex failing
by JavaFan (Canon) on Feb 03, 2011 at 10:12 UTC
    Let's see, your match has to start with a semi-colon, followed by a slash, followed by not a slash. The only semi-colon in your string is followed by two slashes. No match.
Re: Regex failing
by fisher (Priest) on Feb 03, 2011 at 10:09 UTC
    No-no-no, why do you think it should not fail?
    And hint: you can use different separators instead of slashes - s/find/replace/ can be s|find|replace, for example.
      Where is my understanding wrong?
      (my $file_name) = $line =~ / \/ #match a front slash "/" [^\/]#dont match any more frontslashes (.*)#match everything after / and save \s-\s#match a " - " /;
        Hmmm... semicolon? previously you said it begins with semicolon:
        (my $file_name) = $line =~ /;\/[^\/](.*)\s-\s/;
Re: Regex failing
by wind (Priest) on Feb 03, 2011 at 14:29 UTC

    It appears that most everyone has already pointed out the faults and possible ways of debugging your problem.

    Here's one possible solution depending on what you want in the end, whether it's the file name or the full file path. This just relies on the set border of ' - ' and greedy matching of valid characters:

    my $line = '\amss\products\76xx\wconnect\bthost\brew\statext\src\aeebt +extag.c-36572;' . 'FILE.flf;//source/wconnect/bthost/brew/statext/rel/00.00.26/src +/AEEBTExtAG.c - ' . 'LABEL : 1'; (my $file_name) = $line =~ m{([^/]+) - }; print "$file_name\n"; # AEEBTExtAG.c (my $file_path) = $line =~ m{;/([^;]+) - }; print "$file_path\n"; # /source/ ... /AEEBTExtAG.c

    -Miller