Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Trimming Paths with regexes

by TGI (Parson)
on Aug 30, 2001 at 01:08 UTC ( [id://108903]=perlquestion: print w/replies, xml ) Need Help??

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

As part of a project I'm working on, I need to play with a path-like data structure. It comes in the form '/foo/bar/baz'. I need to check the full path, then '/foo/bar', then '/foo' and finally '/'.

So I've put together a do {} while loop that terminates when the path variable is length 0. I'm using a regex to trim the path:

do { if (exists $o->{$path}) { # Do stuff } # trim path print "\t\t$path\n"; $path =~ s:(^/$)|((?<=^/)[^/]+$)|(/[^/]+$)::x; } while ( length $path > 0 );

I keep futzing with the regex and can't come up with something that works. I keep failing to get '/' processed.

Once again, here's the transformation I'm looking for:

 '/foo/bar'-> '/foo'
 '/foo' ----> '/'
 '/' -------> ''


TGI says moo

Replies are listed 'Best First'.
Re: Trimming Paths with regexes
by jryan (Vicar) on Aug 30, 2001 at 01:21 UTC

    I had to deal with a similar situation one time. Instead of fiddling with a regex all day, I used split to split the path up, and then put it back together (minus the last part). It was similar to this:

    my $oldpath = "/foo/bar/baz"; my @path = split(/\//, $oldpath); my $newpath = ""; for ($i=0; $i<(@path-1); $i++) { $newpath .= "/".$path[$i]; } print $newpath;

    It might not be as cleany coded as a regex (or as cool looking!), but it gets the job done. Sometimes the simple solutions are the best :)

Re: Trimming Paths with regexes
by damian1301 (Curate) on Aug 30, 2001 at 01:15 UTC
    I personally would find it much more easier to just split the string and then work with it from there.

    $_.=($=+(6<<1));print(chr(my$a=$_));$^H=$_+$_;$_=$^H; print chr($_-39); # Easy but its ok.
Re: Trimming Paths with regexes
by demerphq (Chancellor) on Aug 30, 2001 at 05:24 UTC
    my $path='/foo/bar'; my @dirs=split(/\//,$path); $"='/'; $\="\n"; while (@dirs) { my $str="@dirs" || "/"; print $str; pop @dirs; }
    outputs
    /foo/bar /foo /
    Yves
Re: Trimming Paths with regexes
by dga (Hermit) on Aug 30, 2001 at 01:48 UTC

    Returns the path shortened and handles paths with //'s together like ////usr/bin correctly. Returns undef in the special case of the root path. Does not handle relative paths

    sub pathtrim { my($path)=@_; return undef if($path eq '/'); $path =~ s#/[^/]+$#/#; $path =~ s#(/[^/]*)/+$#$1#; return $path; }
Re: Trimming Paths with regexes
by Hofmator (Curate) on Aug 30, 2001 at 14:43 UTC

    Just to show that it's not too complicated with a regex:

    do { # your stuff here print "\t\t$path\n"; } while $path =~ s#(?:(^/)|/)[^/]+$#$1?$1:''#e;
    You can use a subroutine as well, then the regex is pretty simple if you handle the special case beforehand:
    sub pathtrim { my ($path) = @_; return '/' if ($path =~ m#^/[^/]+$/); $path =~ s#/[^/]+$##; return $path; }

    Update: Fixed small bug in the subroutine.

    -- Hofmator

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://108903]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (2)
As of 2025-06-22 00:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.