use File::Basename;
my $path = "a/b/c/d";
my $dirpath = basename ($path);
my $basepath = dirname ($path);
my $base_basepath = dirname ($basepath);
my $dir_dirpath = basename ($basepath);
print "$dir_dirpath/$dirpath\n";我要打印c/d (即列表dir/filename)。以上是最好的方法吗?很明显,上面的方法很有效,但我还是不喜欢。有没有一种更好/更酷/更有效的方法来做到这一点?就像一场regex比赛??
实际上,这个程序只是完成了我真正想要做的一部分。这些是不同的用例以及预期的结果:
a/b/c/d => c/d d
b/c/d => c/d d
/c/d => c/d d
c/d => c/d d
/d => d
d => d发布于 2013-02-10 14:52:17
File::Spec模块是操纵文件路径的规范和可移植的方式,而File::Spec::Functions允许直接访问该模块的函数,而不必在任何地方都以File::Spec->作为前缀。
use strict;
use warnings;
use File::Spec::Functions qw/ splitdir catdir /;
my $path = "a/b/c/d";
my @path = splitdir $path;
print catdir @path[-2,-1];输出
c/d发布于 2013-02-10 14:19:27
一种使用拆分的方法
#!/usr/bin/perl
my $z="a/b/c/d";
my ($a, $b, $c, $d) = split ('/', $z);
print "$c/$d";只使用正则表达式
#!/usr/bin/perl
my $z = "a/b/c/d";
($a, $b) = $z[$cnt] =~ m#(\w+){0,1}/{0,1}(\w+)$#;
printf "$a/$b - $b\n";注意:这种方法寻找后继dir1 1/dir1 2,并将它们保存到$a和$b中。美元符号($)强制将匹配定位到字符串的末尾,因此它匹配右侧或$z。{0,1}允许我们匹配在那里的东西,如果它是存在的,但如果不是,那么就忽略它。这些都是/d和d案例所必需的。
所有可能的路径演示
#!/usr/bin/perl
my @z = qw(a/b/c/d b/c/d /c/d c/d);
for (my $cnt = 0; $cnt <= 3; $cnt++) {
($a, $b) = $z[$cnt] =~ m#(\w+){0,1}/{0,1}(\w+)$#;
printf "%10s - %s/%s - %s\n", $z[$cnt], $a, $b, $b;
}
### output
% ./script.pl
a/b/c/d - c/d - d
b/c/d - c/d - d
/c/d - c/d - d
c/d - c/d - d
/d - /d - d
d - /d - d这仅仅表明这种方法适用于问题中提到的目录。
注意:这种方法确实有它的缺点。它只在UNIX系统上工作,需要特别注意目录名的(\w+)匹配器。如果目录中有空格,这将失败。
https://stackoverflow.com/questions/14798397
复制相似问题