如何在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