如何检查路径是否是perl中另一个的子路径?

时间:2016-04-25 10:51:35

标签: perl filesystems

在其他语言中,这个问题有一些答案。我是perl的新手,我正在这样做(比使用文件系统函数更多地比较字符串):

use File::Spec;

sub has_common_prefix {
  my ($path, $subpath) = @_;
  $path = uc (File::Spec->canonpath($path))."\\";
  $subpath = uc (File::Spec->canonpath($subpath));

  if ( substr($subpath, 0, length($path)) eq $path ) return 1;
  return 0;
};

has_common_prefix('c:\\/abCD/EFgh', 'C:\abcd\\efgh/ijk.txt');

我想知道是否有更好的方法可以做到这一点,更多的是“perlisch”: - )

感谢。

2 个答案:

答案 0 :(得分:0)

我已经攻击了这个,但我并不为此感到骄傲,我希望有人能提出更好的建议。我搜索了CPAN但很惊讶没有发现任何相关的

我的想法是使用File::Spec::Functions中的abs2rel函数。这没关系,除非它为此目的而努力,并且会为../..返回abs2rel('/usr', '/usr/a/b')。它还将在使用路径中的卷的系统上返回第一个值

这只是将abs2rel包含在函数is_within中,它拒绝这两种情况,但否则返回完整的相对路径(真值)。这意味着is within('/usr', '/usr')将返回.,这是真的,但如果您认为某个目录不应包含自身,则可以针对该特定情况对其进行测试

注意 ,这不会检查路径是否是目录,也不检查路径是否存在

use strict;
use warnings 'all';

use File::Spec::Functions qw/ abs2rel  file_name_is_absolute  updir /;

my @pairs = (
    [qw{ /usr      /usr/bin } ],
    [qw{ /usr/etc  /usr/bin } ],
    [qw{ /var      /usr/bin } ],
    [qw{ /usr/bin  /usr/bin } ],
);

for ( @pairs ) {
    my ($path, $subpath) = @$_;
    my $within = is_within($subpath, $path);
    printf qq{"%s" is %swithin "%s"  (%s)\n},
            $subpath,
            ($within ? '' : 'not '),
            $path,
            $within // 'undef';
}


sub is_within {
    my ($path, $container) = @_;

    my $a2r = abs2rel($path, $container);

    return if file_name_is_absolute($a2r) or index($a2r, updir) == 0;

    $a2r;
}

输出

"/usr/bin" is within "/usr"  (bin)
"/usr/bin" is not within "/usr/etc"  (undef)
"/usr/bin" is not within "/var"  (undef)
"/usr/bin" is within "/usr/bin"  (.)

答案 1 :(得分:0)

File :: Spec及其替换Path :: Class不会触及文件系统,因此他们不会处理大小写差异,并且他们不会处理短形式和长形式。“ / p>

=INDEX($A$1:$A$8,MATCH(F1,$B$1:$B$8,0))