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

ok, now i have a question that im sure someone could answer... it's about returning a list of strings from a string. i am making a web database, and i have it going actually pretty well so far, but ive gotten snagged a bit. in my monk-like quest to make my site look a little like yah00 in the way it shows oyu what category you're in, the database gets 2 strings from a local config file: the directory hirearchy you're in (your full directory path, minus all that /home/user/web/ stuff) and the category name hirearchy (for each directory, there's a category name, and it is put liek a directory listing). ok, this isnt confusing cuz the entry looks like this:
CurrCat: /Main/PC Stuff -_-_/webdbase/PC
the "/Main/PC Stuff" is the categories for "/webdbase/PC". so, the directory for category "Main" is "webdbase" and the directory for category "PC Stuff" is "PC". now, i have to return that so it looks like this on the web page: "::/Main::/PC" with a link to "Main" and a link to "PC". This is sorta working with about 3 lines of code (3 for the directory array and 3 for the category array) but the arrays are different... where the category array just has a different category for each entry in the array, the directory entries have to contain the FULL PATH (relative to the web server) for each link. so, the array would look a bit like this for the categories: ("Main", "PC") and like this for the directories: ("/webdbase", "/webdbase/PC"). Now that i have thoroughly confused you, here is the code that i have used to try and do this. it does not work, cuz the FULL directory path is not put in properly (from my testing).
while ($CURRDIR =~ m/\//) { unshift (@dacurdirs, substr($CURRDIR, rindex($CURRDIR, "/"))); $CURRDIR = substr($CURRDIR, 0, index($CURRDIR, "/")); } while ($CURRCAT =~ m/\//) { unshift (@dacurcats, substr($CURRCAT, rindex($CURRCAT, "/"))); $CURRCAT = substr($CURRCAT, index($CURRCAT, "/"), rindex($CURRCAT, "/" +)); }
if anyone could just fix that thing directory part so it puts the ful path id be grateful.

Replies are listed 'Best First'.
Re: Messing with a substring
by greenFox (Vicar) on Apr 01, 2001 at 06:24 UTC
    A couple of hints- its much better to use File::Basename for messing with paths. If you use a hash to store your data then you can just do a lookup $curdir=$categories{$category};
    HTH.

    --
    my $chainsaw = 'Perl';

      dude, you sorta missed it there... it's not actual paths im messing with, i need to take 1 string (a directory path) and split it into a bunch of strings, 1 for each directory in the path. and they have to retain their full path name. i know how to use hashes but dont need to since an array is the best way for me to go through all the elements (paths) in the array. so, i was thinking maybe appending to a separate string the last path that worked and work my way up, but i tried that and now my script just times out on my webpage and on console there are no debugging problems so ugh! this is my idea so far, please someone tell me where i went wrong and how can i make it work?
      $oldCOORRDIR =""; while ($CURRDIR =~ m/\//) { $COORRDIR = substr($CURRDIR, 0, index($CURRDIR, "/")); unshift (@dacurdirs, "$oldCOORRDIR/$COORRDIR"); $oldCOORRDIR = $COORDIR; $CURRDIR = substr($CURRDIR, index($CURRDIR, "/")); }

        I'm pretty damn sure I don't understand the problem at all... But maybe, just maybe... Anyway, I'll give it a shot. How about:

        my $str = "/One/Two/Three"; my @paths = ($str); push @paths, $str while($str =~ s{^(/.+)/[^/]*$}{$1}); print "$_\n" for @paths;

        That prints:

        /One/Two/Three /One/Two /One

        Is that at all what you're looking for?

        Update: Of course, that's destructive to $str so be sure it's a copy.

        bbfu
        Seasons don't fear The Reaper.
        Nor do the wind, the sun, and the rain.
        We can be like they are.

(dkubb) Re: (2) Messing with a substring
by dkubb (Deacon) on Apr 02, 2001 at 04:46 UTC

    The nodes in this thread have focused on using regexes and substr to parse a directory path. IMHO, it might be a better idea to use a module called File::Spec, which is specifically designed for this, and works across a few different platforms, which is a nice bonus.

    Here's an example script using this module to produce the output you're looking for:

    #!/usr/bin/perl -wT use strict; use File::Spec; use Data::Dumper qw(Dumper); use constant PATH => '/One/Two/Three'; #split up the path into directory segments my @dirs = File::Spec->splitdir(PATH); my @paths; while(my $path = File::Spec->catfile(@dirs)) { push @paths, $path; pop @dirs; } print Dumper(\@paths);

    which prints out:

    $VAR1 = [ '/One/Two/Three', '/One/Two', '/One' ];