Are these answers correct?
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11145493
use warnings;
for my $path ( qw(
/a/b/c/d/../../../e
/a/../b/./c//d
../invalid_do_not_change
./tmp
/tmp/../../../tmp
A//B A/B/ A/./B A/foo/../B
) )
{
local $_ = $path;
1 while s{
/+(?=/) | # multiple ///
^/..(?=/) | # stay at root
/\z | # remove trailing /
(?<=/)(?!\.\./)[^/]+/\.\./ | # remove 'name/../'
(?<![^/])\./ # remove ./
}{}x;
printf "%30s -> %s\n", $path, $_;
}
Outputs:
/a/b/c/d/../../../e -> /a/e
/a/../b/./c//d -> /b/c/d
../invalid_do_not_change -> ../invalid_do_not_change
./tmp -> tmp
/tmp/../../../tmp -> /tmp
A//B -> A/B
A/B/ -> A/B
A/./B -> A/B
A/foo/../B -> A/B