为什么以下两个正则表达式的行为不同?
$millisec = "1391613310.1";
$millisec =~ s/.*(\.\d+)?$/$1/;
VS
$millisec =~ s/\d*(\.\d+)?$/$1/;
此代码不打印任何内容:
perl -e 'my $mtime = "1391613310.1"; my $millisec = $mtime; $millisec =~ s/.*(\.\d+)?$/$1/; print "$millisec";'
虽然这会打印字符串的小数部分:
perl -e 'my $mtime = "1391613310.1"; my $millisec = $mtime; $millisec =~ s/\d*(\.\d+)?$/$1/; print "$millisec";'
答案 0 :(得分:8)
在第一个正则表达式中,.*
占用了字符串末尾的所有内容,因此可选的(.\d+)?
无法获取。 $1
将为空,因此字符串将替换为空字符串。
在第二个正则表达式中,只从头开始抓取数字,以便\d*
在点前停止。 (.\d+)?
将选择点,包括尾随数字。
您在括号内使用.\d+
,它将匹配任何字符加数字。如果要明确匹配点,则必须使用\.
。
要使第一个正则表达式与第二个正则表达式相似,您必须编写
$millisec =~ s/.*?(\.\d+)?$/$1/;
这样最初的.*
就不会占用所有内容。
答案 1 :(得分:1)
贪婪。
Perl的正则表达式引擎将与每个术语尽可能匹配,然后再继续下一学期。因此.*(.\d+)?$
.*
匹配整个字符串,(.\d)?
匹配任何内容,因为它是可选的。
\d*(.\d+)?$
只能与点匹配,因此必须将.1
与(.\d+)?
匹配