Regex Perl中用于替换的匹配数字
我有一个小剧本:Regex Perl中用于替换的匹配数字,regex,perl,substitution,Regex,Perl,Substitution,我有一个小剧本: my @list = ('R3_05_foo.txt','T3_12_foo_bar.txt','01.txt'); foreach (@list) { s/(\d{2}).*\.txt$/$1.txt/; s/^0+//; print $_ . "\n"; } 预期的产出将是 5.txt 12.txt 1.txt 但是相反,我得到了 R3_05.txt T3_12.txt 1.txt 最后一个很好,但我无法理解为什么正则表达式在这种情况下为我提
my @list = ('R3_05_foo.txt','T3_12_foo_bar.txt','01.txt');
foreach (@list) {
s/(\d{2}).*\.txt$/$1.txt/;
s/^0+//;
print $_ . "\n";
}
预期的产出将是
5.txt
12.txt
1.txt
但是相反,我得到了
R3_05.txt
T3_12.txt
1.txt
最后一个很好,但我无法理解为什么正则表达式在这种情况下为我提供了$1
的字符串开头。试试这种模式
foreach (@list) {
s/^.*?_?(?|0(\d)|(\d{2})).*\.txt$/$1.txt/;
print $_ . "\n";
}
说明: 我在这里使用分支重置功能(即,
(?|…()…|…())
),它允许在一个引用中放置多个捕获组($1
)。因此,您可以避免使用第二个替换来修剪捕获左侧的零
要删除数字前开头的所有内容,我使用:
.*? # all characters zero or more times
# ( ? -> make the * quantifier lazy to match as less as possible)
_? # an optional underscore
请注意,您可以确保只有2个数字添加一个前瞻,以检查是否有以下数字:
s/^.*?_?(?|0(\d)|(\d{2}))(?!\d).*\.txt$/$1.txt/;
(?!\d)
表示后面没有数字。我将修改您的正则表达式。尝试使用以下代码:
my @list = ('R3_05_foo.txt','T3_12_foo_bar.txt','01.txt');
foreach (@list) {
s/.*(\d{2}).*\.txt$/$1.txt/;
s/^0+//;
print $_ . "\n";
}
问题是,
s//
中的第一部分与您认为它的功能相匹配,但第二部分并没有取代您认为它应该取代的功能<代码>s//将仅替换先前匹配的内容。因此,要替换类似于T3\uu
的内容,您也必须匹配它
s/.*(\d{2}).*\.txt$/$1.txt/;
这里的问题是替换正则表达式不覆盖整个字符串,因此只替换部分字符串。但是,对于一个简单的问题,您使用的是一个相当复杂的解决方案 似乎您想要的是从字符串中读取两位数字,然后在其末尾添加
.txt
。那么,为什么不这样做呢
my @list = ('R3_05_foo.txt','T3_12_foo_bar.txt','01.txt');
for (@list) {
if (/(\d{2})/) {
$_ = "$1.txt";
}
}
要克服前导零效应,可以通过向数字加零来强制转换为数字:
$_ = 0+$1 . ".txt";
我以前有过,但我的输出只有一位数。确定吗?我的输出:perl test.pl 5.txt 12.txt 1.txt