Perl正则表达式没有给出预期的结果

时间:2014-10-03 02:58:09

标签: regex perl

我有以下代码

  my $string = 'ban-3.1.2278-1.x86_64.1.rpm';
  my ($substr) = ($string =~ /(.+)-\d(.+)/);
  print "Result: $substr\n";

我原本期待它返回禁令但是它的回归禁令 - 3.1.2278,我无法弄明白为什么。 任何人都可以解释一下,为什么它的行为方式如此,并且有正确的方法吗?

谢谢。

4 个答案:

答案 0 :(得分:2)

因为任何字符.都会匹配破折号。

如果您想限制匹配,请使用字符类或非贪婪匹配.*?

my $string = 'ban-3.1.2278-1.x86_64.1.rpm';
my ($substr) = $string =~ /([^-]*)-\d(.+)/;
print "Result: $substr\n";

输出:

Result: ban

答案 1 :(得分:1)

您需要在.+之后添加量词?,使第一个捕获组内的+变为非贪婪,以便它可以进行不情愿的匹配(即,最短的匹配) )否则它将进行最长的匹配。

(.+?)-\d(.+)

代码:

my $string = 'ban-3.1.2278-1.x86_64.1.rpm';
my ($substr) = ($string =~ /(.+?)-\d(.+)/);
print "Result: $substr\n";

输出:

Result: ban

答案 2 :(得分:1)

Split也可以满足您的期望。试试这个

my $string = 'ban-3.1.2278-1.x86_64.1.rpm';
my @substr = split('-',$string);
print "Result: $substr[0]\n";

输出

Result: ban

此脚本由存储在数组中的-拆分。然后使用索引键值$substr[0]

打印禁令

答案 3 :(得分:0)

在上面的代码“my($ substr)=($ string =〜/(.+?)-\d(.+)/);”中,使用了不必要的分组。使用以下代码代替,

my $string = 'ban-3.1.2278-1.x86_64.1.rpm'; 
$string =~ /([a-z]+)-/i; 
print "Result: $1";

如果您只需要答案,“禁止”表示使用此代码。

[a-z] + - 它匹配多个连续字母字符(准确匹配)。

- 它用于区分大小写。

$ 1 - 它返回第一个分组的值。

<强>输出

Result: ban