my $str = "/One/Two/Three"; # Start with the whole thing in the array. You could # start with @paths = () if you'd rather not include # the current directory/path/category/whatever. my @paths = ($str); while( # Spreading this out so I can comment it... $str =~ s[ ^ # Match from the start of the string... ( # Save this in $1 / # The first / .+ # Followed by one or more 's # (including /'s!!), all the way up to # the last / (see below) ) # Don't save anything else in $1 / # The very last / in the string. This # is what causes the above .+ to stop # before the end of the string. [^/]* # We want an optional word after # the last / but NOT /'s (otherwise # it wouldn't be the last one, would it?) $ # Make sure don't stop before the end # of what's left of the string. ][$1]x # Replace it all with $1, which contains # everything up to (but not including) # the last /. Note the x option, let's us # include comments and space it out. ) { # Push the current version of $str onto the list. # It's whatever we have left after chopping off # the last word and it's /. push @paths, $str; }