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

使用Excel::Writer::XLSX无法输出数字名称目录的Perl问题

问题概述

我用Perl编写了一段遍历指定目录及其子目录、文件的代码,打算通过Excel::Writer::XLSX将内容输出到Excel表格。目前遇到的问题是:像“1”“2.4”这类数字命名的目录能正常遍历,但目录名称无法打印到Excel中,执行后弹出警告:

Argument "" isn't numeric in addition (+) at /home/priyansh.mehta/perl5/lib/perl5/Excel/Writer/XLSX/Worksheet.pm line 2510

我只需要目录和文件的名称而非完整路径,因此用正则表达式提取名称,相关代码如下:

use Excel::Writer::XLSX;  
my $workbook= Excel::Writer::XLSX->new( 'myExcel.xlsx' );  
my $ws = $workbook->add_worksheet();  
$path = "path_name";
{
    $i= 0;
    $j = 0;
    sub dir_listing {
        my ($root) = @_;
        $root .= '/';
        for my $f (glob "$root*")
        {
            if (-d $f)
            {
                $f =~ m/.*/(.*)/;
                $ws->write($i,$j,$1);
                $j++;
                dir_listing($f);
                $j--;
            }
            if (-f $f)  
            {
                $f =~ m/.*/(.*)/;
                $ws->write($i,$j,$1);
                $i++;
            }
        }
    }
}
dir_listing($path);
问题原因与解决办法

核心问题:正则匹配失效导致空值

你使用的正则表达式m/.*/(.*)/存在逻辑错误——.*会匹配整个路径字符串,后续的(.*)只能捕获到空字符串,所以$1经常是空值。当空值被传入write方法时,Excel::Writer::XLSX内部会将其当作数字参与运算,从而触发警告,同时无法正确写入目录名称。

正确提取名称的方法

不要用正则硬拆路径,Perl内置了File::Basename模块,其中的basename函数可以精准提取路径最后一级的目录或文件名,比正则表达式更可靠且不易出错。

修改后的完整代码

use Excel::Writer::XLSX;
use File::Basename;  # 引入路径处理模块

my $workbook = Excel::Writer::XLSX->new( 'myExcel.xlsx' );
my $ws = $workbook->add_worksheet();
my $path = "path_name";

{
    my $i = 0;  # 用my声明变量,限制作用域避免全局污染
    my $j = 0;
    sub dir_listing {
        my ($root) = @_;
        # 统一路径结尾的斜杠,避免重复添加导致glob匹配异常
        $root .= '/' unless $root =~ m{/$};
        
        for my $f (glob "$root*") {
            if (-d $f) {
                my $name = basename($f);  # 提取目录名
                $ws->write($i, $j, $name);
                $j++;
                dir_listing($f);
                $j--;
            }
            if (-f $f) {
                my $name = basename($f);  # 提取文件名
                $ws->write($i, $j, $name);
                $i++;
            }
        }
    }
}

dir_listing($path);

额外优化点

  • 用my声明$i和$j,将变量限制在代码块作用域内,避免全局变量引发的意外问题。
  • 优化路径结尾斜杠的处理逻辑,防止重复添加斜杠导致glob匹配出错。

内容的提问来源于stack exchange,提问作者Priyansh Mehta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 06:25:09