[Vienna-pm] Pfad säubern

Stefan Weiss spaceman at foo.at
Sun Jul 10 06:48:44 PDT 2005


On 2005-07-10 13:07, peter pilsl wrote:
> ich verwende folgenden ansatz:
> 
> i) pfad normieren, damit er immer oder nie leading bzw. trailing slashes 
> hat.
> 
> ii) loop
> 
> /xxx/../  => /
> /./       => /

Den leading Slash lass ich lieber dran :-)
Ich habe jetzt eine ganz andere Lösung genommen und die Regexen weggelassen:

# usage: $path = minimize_path($path)
sub minimize_path {

    my @parts = split "/", shift;
    my $i = 0;
    while ($i < @parts) {
        if ($i && $parts[$i] eq "") {
            splice @parts, $i, 1;
            next;
        } elsif ($i && $parts[$i] eq "..") {
            if ($i == 1) {
                splice @parts, $i, 1;
                $i = $i > 1 ? $i - 2 : 0;
                next;
            } elsif ($parts[$i - 1] ne "..") {
                splice @parts, $i - 1, 2;
                $i = $i > 1 ? $i - 2 : 0;
                next;
            }
        } elsif ($parts[$i] eq "." && @parts > 1) {
            splice @parts, $i, 1;
            next;
        } elsif ($i && $i + 1 == @parts && $parts[$i] eq "") {
            pop @parts;
            --$i;
            next;
        }
        ++$i;
    }
    return join "/", @parts;

}

Die Performance ist halbwegs vergleichbar mit der (mittlerweile etwas
verbesserten) Regex-Lösung:

         Rate split regex
split 16129/s    --  -24%
regex 21277/s   32%    --

...wobei ich auch einen richtig pathologischen Pfad zum Testen verwendet
habe ("////../foo/bar/blomm/../..//baz/./blimm/../..//"), bei dem die
Schleife sehr oft durchlaufen wird. Ich schätz mal im Normalfall sind
beide Lösungen gleich schnell, nur bin ich mir bei der split-Variante
sicherer, was das Resultat betrifft. Ausserdem hat man hier nur zwei
Stellen, an der der Path-Delimiter angegeben ist, was vielleicht auch
dem Maroš was bringt.


cheers,
stefan


More information about the Vienna-pm mailing list