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

Hi All, Sorry for rewriting this query again since I couldn't provide code. I have following piece of code to fetch intermediate and last node of a string, i.e windows path or list of windows path. Here I want to fetch a word based on delimiter "\". some of input lines are as follows. Here I want to fetch "axy" and "#@$#@$@" from the below lines using the key pattern $key="C:\abc\dfg"; The code is:
The arrary contents are 1. C:\abc\dfg\axy 2. C:\abc\dfg\#@$#@$@\hwllo $key="C:\abc\dfg" $key=~s/(\\[!@#$%^&(),.\}\{[\]+-])/\\$1/g; $line=~s/(\\[!@#$%^&(),.\}\{[\]+-])/\\$1/g; if( $line =~ /$key\\\S+\\/){ # if this is not node ($pat)=$line=~/$key\\(\S+)\\/; }else{ # if end node ($last_node)=$line=~/$key\\(.*)/; }
What is wrong in this reg exp... Can any one help me out here? Thanks, Sunil
  • Comment on unable to fomulate right regular expression to fetch the intermediate and last word from a line (windows path) using delimiter "\"
  • Download Code

Replies are listed 'Best First'.
Re: unable to fomulate right regular expression to fetch the intermediate and last word from a line (windows path) using delimiter "\"
by GrandFather (Saint) on Sep 08, 2010 at 00:41 UTC

    First always use strictures (use strict; use warnings;). That will tell you that \a, \d, \# and \h are not what you expect. It would also tell you that you are redefining $key which is probably not what you meant.

    You seem to be confusing the roles of $key and $line.

    Your regex matches a bunch of weird characters. It may be that you mean to match the complement of the set, in which case the set should start [^.

    You would likely get much better answers if you told us what the problem is that you are trying to solve and showed us a little more of the code. It looks like you are trying to manipulate paths - you've already been told several times about modules that will help you with that.

    True laziness is hard work
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: unable to fomulate right regular expression to fetch the intermediate and last word from a line (windows path) using delimiter "\"
by graff (Chancellor) on Sep 08, 2010 at 02:18 UTC
    Your "code snippet" begins with:
    The array contents are ...
    But there is no array in the code snippet, and this makes your post incoherent. (That means we can't understand what you are trying to ask us about.)

    I think one or more monks, in replying to one or more of your earlier posts, has mentioned modules like File::Spec and File::Basename. Have you looked into those? Have you tried them? Is there some problem that you have with trying them?

    Others have also told you about using split -- e.g. like this:

    my @a = qw/C:\abc\dfg\axy C:\abc\dfg\#@$#@$@\hwllo/; for ( @a ) { my @p = split /\\/; print "last-component= ", $p[-1], " and next-to-last= ", $p[-2], " +\n"; }
    Have you tried anything like that yet? Is there some problem with trying that?
Re: unable to fomulate right regular expression to fetch the intermediate and last word from a line (windows path) using delimiter "\"
by bart (Canon) on Sep 08, 2010 at 08:05 UTC
    Enough people have already focused on your wrong assumption of what you put in your path string ("$key), and thus why it cannot possibly work as you intended.

    But, Perl being the TIMTOWTDI language that it is, I'd like to point out to a different approach, and that is using the modules File::Spec (or its procedural variant File::Spec::Functions), and possibly File::Basename for extracting the full directory and path and the base filename, from a path.

    Specifically, you could use abs2rel, like this:

    my $key = "C:\\abc\\dfg"; my @example = ("C:\\abc\\dfg\\axy", "C:\\abc\\dfg\\#\@\$#\@\$\@\\hwllo +"); use File::Spec::Functions qw(abs2rel); foreach (@example) { my $rel = abs2rel($_, $key); printf "in: %s\nout: %s\n\n", $_, $rel; }
    Result:
    in: C:\abc\dfg\axy out: axy in: C:\abc\dfg\#@$#@$@\hwllo out: #@$#@$@\hwllo
    I believe that's something you can start out with.

    Furthermore, if you're interested in getting the top level directory (?) name from that result, you can use the function splitdir from File::Spec::Functions:

    # modified source use File::Spec::Functions qw(abs2rel splitdir); foreach (@example) { my $rel = abs2rel($_, $key); my($topdir) = splitdir($rel); printf "in: %s\nout: %s\ntop directory: %s\n\n", $_, $rel, $topdir +; }
    New output:
    in: C:\abc\dfg\axy out: axy top directory: axy in: C:\abc\dfg\#@$#@$@\hwllo out: #@$#@$@\hwllo top directory: #@$#@$@
Re: unable to fomulate right regular expression to fetch the intermediate and last word from a line (windows path) using delimiter "\"
by CountZero (Bishop) on Sep 08, 2010 at 06:15 UTC
    I think we are all getting confused.

    Do you perhaps mean to get the path-component, just after the --what you call-- key? It just happens to be the last and next-to-last component in your examples, but that is just sheer co-incidence.

    The following code will extract the next path-element after the key:

    use strict; use warnings; use 5.012; my $key= quotemeta 'C:\abc\dfg'; # we must escape all meta-characters while (<DATA>) { chomp; if (/$key\\([^\\]+)/) { say "$_ : $1"; } else { say "$_ : no match"; } } __DATA__ C:\abc\dfg\axy C:\abc\dfg\#@$#@$@\hwllo C:\abc\dfg
    Output:
    C:\abc\dfg\axy : axy C:\abc\dfg\#@$#@$@\hwllo : #@$#@$@ C:\abc\dfg : no match

    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