Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

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 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 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 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; }
    /foo/bar /foo /
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?

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

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (12)
As of 2024-04-23 14:59 GMT
Find Nodes?
    Voting Booth?

    No recent polls found