You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Perl提取含多圆点文件名的文件名与扩展名

解决Perl中含多圆点文件名的提取问题

嘿,我来帮你搞定这个多圆点文件名的提取问题!你的现有代码用split(/\./)会把所有圆点都作为分隔符,所以遇到文件名里带多个点的情况就卡壳了——我们真正需要的是以最后一个圆点为分界,前面的是文件名,后面的是扩展名,对吧?

方案1:用正则表达式精准分割

我们可以用正则只匹配最后一个圆点(也就是后面跟着扩展名的那个点),避免把文件名里的圆点误拆。这里有两种直观的写法:

写法A:带正向预查的split

修改循环里的分割逻辑,把全量拆分换成只拆分最后一个圆点:

my @fields = split(/\.(?=[^.]+$)/, $recordLine, 2);
  • 正则\.(?=[^.]+$)的作用:匹配一个圆点,同时要求这个圆点后面必须跟着「至少一个非圆点字符直到字符串结尾」(正向预查(?=...)不会消耗字符,只是做条件判断)
  • 最后加, 2是限制最多分割成2部分,避免意外拆分

修改后的完整代码:

use strict;
use warnings;
print "Perl Starting ... \n\n";
open my $input_filehandle1, '<', 'test1.txt' or die "No input Filename Found test1.txt ... \n";
while (defined(my $recordLine = <$input_filehandle1>)) {
    chomp($recordLine);
    # 仅分割最后一个圆点
    my @fields = split(/\.(?=[^.]+$)/, $recordLine, 2);
    # 兼容无扩展名的情况(按需保留)
    if (@fields == 2) {
        print "FileName: $fields[0] ... Ext: $fields[1] ... \n";
    } else {
        print "FileName: $fields[0] ... Ext: (no extension) ... \n";
    }
}#end while-loop
print "\nPerl End ... \n\n";
1;

写法B:正则捕获分组

另一种更易读的方式是直接用正则捕获文件名和扩展名:

while (defined(my $recordLine = <$input_filehandle1>)) {
    chomp($recordLine);
    if ($recordLine =~ /^(.*)\.([^.]+)$/) {
        my $filename = $1;
        my $ext = $2;
        print "FileName: $filename ... Ext: $ext ... \n";
    } else {
        print "FileName: $recordLine ... Ext: (no extension) ... \n";
    }
}

这个正则^(.*)\.([^.]+)$的逻辑:

  • (.*):捕获任意字符(尽可能多,直到最后一个圆点)作为文件名
  • \.:匹配最后一个圆点
  • ([^.]+)$:捕获所有非圆点字符直到结尾作为扩展名

方案2:用Perl自带的File::Basename模块(更专业)

如果以后需要处理带路径的文件名,或者想更规范地解析文件名,推荐用Perl核心模块File::Basename——它专门为文件名处理设计,健壮性拉满:

修改后的代码:

use strict;
use warnings;
use File::Basename; # 引入核心模块

print "Perl Starting ... \n\n";
open my $input_filehandle1, '<', 'test1.txt' or die "No input Filename Found test1.txt ... \n";
while (defined(my $recordLine = <$input_filehandle1>)) {
    chomp($recordLine);
    # fileparse第二个参数是匹配扩展名的正则,这里匹配最后一个点及后续内容
    my ($filename, $path, $ext) = fileparse($recordLine, qr/\.[^.]*/);
    # 去掉扩展名前面的圆点(如果需要带点的扩展名可以直接用$ext)
    my $clean_ext = substr($ext, 1);
    print "FileName: $filename ... Ext: $clean_ext ... \n";
}#end while-loop
print "\nPerl End ... \n\n";
1;

这个方法的优势在于,即使输入里包含完整路径(比如/data/docs/amazing c. document.docx),它也能正确提取文件名和扩展名,无需额外处理路径部分。

最终测试结果

不管用哪种方案,运行后都会得到你期望的输出:

Perl Starting ... 
FileName: test word document ... Ext: docx ... 
FileName: amazing c. document ... Ext: docx ... 
FileName: 1. 2. 3.45 document ... Ext: docx ... 
Perl End ... 

内容的提问来源于stack exchange,提问作者Sam B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:32:01