如何在Perl中截断特殊情况下的扩展?
我正在编写一个脚本,使用下面的正则表达式截断一个文件的所有扩展名,但似乎效果不好,因为这个命令确实删除了一些我想要的数据,因为它基本上会在看到点时删除所有内容 我目前使用的正则表达式:如何在Perl中截断特殊情况下的扩展?,perl,Perl,我正在编写一个脚本,使用下面的正则表达式截断一个文件的所有扩展名,但似乎效果不好,因为这个命令确实删除了一些我想要的数据,因为它基本上会在看到点时删除所有内容 我目前使用的正则表达式: /\..*?$/ 它将删除一些文件,如 b10_120.00c.current.all --> b10_120 abc_10.77.log.bac.temp.ls --> abc_10 但我正在寻找b10_120.00c和abc_10.77 除此之外,是否有一种打印输出的方法,比如只保留某
/\..*?$/
它将删除一些文件,如
b10_120.00c.current.all --> b10_120
abc_10.77.log.bac.temp.ls --> abc_10
但我正在寻找b10_120.00c
和abc_10.77
除此之外,是否有一种打印输出的方法,比如只保留某个扩展名?例如,对于上述两个示例,它将显示
b10_120.00c.当前
和abc_10.77.日志
。非常感谢。正则表达式中的点应该使用\.
另外,请详细说明如何处理文件名。以下内容将删除文件扩展名:
s/\.[^.]+$//;
解释
\.
匹配文本
[^.]+
匹配每个非
$
直到字符串结束
更新
解释
^
锚定在字符串的开头[^.]+
匹配每个非
\.
匹配文本
[^.]+
匹配每个非
试验
我建议使用以下软件包,而不是正则表达式:
你好,艾伦,谢谢你的回答。我尝试了您提到的b4表达式,例如$string=~s/\.[^.]+$//g,这个表达式只截断了我的最终扩展名。换句话说,如果我用这个表达式,它会给我这个结果-----b10_120.00c.current和abc_10.77.log.bac.temp:不客气。对不起,我误解了。我已经更新了我的答案。嗨,艾伦,谢谢你的回答,但它仍然没有得到我想要的结果,因为你的代码会给出结果(abc_10.77.log.bac.temp.ls和b10_120.00c.current.all),但我想要的是简单的b10_120.00c和abc_10.77。基本上,我当前的$string=~s/\..*?$/命令将帮助我截断所有扩展名,但当文件中有浮点数时,它确实会减少必要的数据。谢谢你的帮助。没问题。在我的更新答案中未进行搜索和替换。因此,您必须使用
$new\u file\u name
作为文件名的精简版本。嗨,艾伦,我是说您的($new\u file\u name)=($file\u name=~m/^([^.]+\.[^.]+)/x);给我这个结果((abc_10.77.log.bac.temp.ls和b10_120.00c.current.all)。我可以知道你有什么想法吗?这样我就可以得到一个简短的结果,比如b10_120.00c和abc_10.77,它们没有减少浮点?这对OP有什么实质性的帮助?要去掉这些内容,@Grace需要逐字列出它们或编写一个正则表达式(qr/
)…这对OP有什么实质性的伤害?这是一个调查选项,可以让OP编写更清晰的代码来去除后缀。事实上,OP已经需要知道她想要删除哪些后缀。这不是误导,也不是明显的愚蠢或与主题无关。据我们所知,OP已经在使用File::Basename::basename
以@suffixlist
参数的形式传递了一个错误的正则表达式。OP需要帮助指定要删除的足够项,而不是删除的机制。(顺便说一句,我没有投你反对票。)
my ($new_file_name) = ( $file_name =~ m/^( [^.]+ \. [^.]+ )/x );
#!/usr/bin/env perl
use strict;
use warnings;
use Test::More 'tests' => 2;
my %file_name_map = (
'b10_120.00c.current.all' => 'b10_120.00c',
'abc_10.77.log.bac.temp.ls' => 'abc_10.77',
);
sub new_file_name {
my $file_name = shift;
my ($new_file_name) = ( $file_name =~ m/^( [^.]+ \. [^.]+ )/x );
return $new_file_name;
}
for my $file_name ( keys %file_name_map ) {
is $file_name_map{$file_name}, new_file_name($file_name),
"Got $file_name_map{$file_name}";
}
$file =~ s/(\.[^.]+).*/$1/; # SO requires 30 chars in answer, that is stupid