从完整路径获取文件名

时间:2010-11-11 11:49:41

标签: regex perl

我需要从完整的文件路径获取文件的名称。我试过用:

$out_fname =~ s/[\/\w+\/]+//;

但是它“吃掉了”文件名的文字。

示例:

表示文件: /bla/bla/folder/file.part.1.file, 它返回: .part.1,file

7 个答案:

答案 0 :(得分:15)

你可以这样做:

use File::Basename;

my $path = "/bla/bla/folder/file.part.1.file";
my $filename = basename($path);

答案 1 :(得分:5)

除了File :: Basename之外,还有Path::Class,它可以用于更复杂的操作,特别是在处理目录或跨平台/文件系统操作时。在这种情况下,它可能有点过分,但可能值得了解。

use Path::Class;

my $file = file( "/bla/bla/folder/file.part.1.file" );
my $filename = $file->basename;

答案 2 :(得分:4)

我同意其他答案,但只想解释你的模式中的错误。正则表达式很棘手,但值得学习。

方括号定义了一类匹配的对象。在您的情况下,它将与正斜杠,单词字符(来自\w),+字符或正斜杠字符(这是多余的)匹配。然后你要说的是匹配其中的一个或多个。有多个字符串可以匹配。它将匹配最早的起始角色,因此第一个/。然后它会尽可能地抓住。

这不是你想要的清楚。例如,如果您的某个目录名中有.,则会停在那里。 /blah.foo/bar/x.y.z会返回.foo/bar/x.y.z

想到这一点的方法是,您希望匹配所有字符,包括最终/

然后所有字符都为斜杠:/.*\//

但为了更安全,请在前面添加一个插入符号,以确保它从那里开始:/^.*\//

要允许前向和反斜杠,请为其创建一个类:/^.*[\/\\]/(即elusive's answer)。

真正的好参考是Learning Perl。有大约3个非常好的正则表达式章节。它们也适用于非Perl正则表达式用户。

答案 3 :(得分:1)

在目录分隔符上使用split是另一种选择。这与使用正则表达式有相同的注意事项(即使用文件名,最好使用其他人已经考虑边缘情况,可移植性,不同文件系统等的模块,因此您不需要在后退和前进上进行匹配-slashes),但作为另一种通用技术很有用,你有一个带有重复分隔符的字符串。

my $file = "/bla/bla/folder/file.part.1.file";
my @parts = split /\//, $file;
my $filename = $parts[-1];

答案 4 :(得分:1)

这是完全我希望它在给定的替换中保留。你是说用什么都不替换最长的斜杠和单词字符串。因此它会抓取所有角色,直到你没有指定的第一个角色并删除它们为止。

它正在做你要求它做的事情。我和其他人一起使用File::Basename来说明你要做的事情。

但这是做同样事情的最快方法:

my $fname = substr( $out_fname, rindex( $out_fname, '/' ) + 1 );

在这里,它说在字符串中找到{em> last 出现的'/'并给我在该位置后面开始的文本。我不是一直反对正则表达式,但它只是表达你真正想做的事情。我不得不长时间做这样的事情,我写了一个last_after子:

sub last_after {
    my ( $string, $delim ) = @_;
    unless ( length( $string ) and my $ln = length( $delim )) {
        return $string // '';
    }
    my $ri = rindex( $string, $delim );
    return $ri == -1 ? $string : substr( $string, $ri + $ln );
}

答案 5 :(得分:0)

我还需要从一堆路径名中拉出最后一个字段。这对我有用:

grep -o '/\([^/]*\)$' inputfile > outputfile

答案 6 :(得分:-1)

这个怎么样:

$out_fname =~ s/^.*[\/\\]//;

它应该删除文件名前面的所有内容。