使用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
相关产品推荐
相关产品推荐

