假设我有:
my $string = "one.two.three.four";
我该如何使用上下文(context)来获取匹配模式的次数(3)?是否可以用一行代码完成?
我尝试了以下代码:
my ($number) = scalar($string=~/\./gi);
我原以为在$number
周围加上括号,可以强制使用数组语境,通过使用scalar
,可以获得计数。然而,我只得到了1
。
这将把正则表达式本身放置在标量上下文中,这不是您想要的。相反,将正则表达式放入列表上下文中(以获取匹配数),并将它放入标量上下文中。
my $number = () = $string =~ /\./gi;
我认为最清晰的描述方式是避免将其立即转换为标量。首先分配到一个数组中,然后在标量上下文中使用该数组。这基本上就是= () =
习惯用语所要做的,但没有(很少使用的)习惯用语:
my $string = "one.two.three.four";
my @count = $string =~ /\./g;
print scalar @count;
$string = "ThisXlineXhasXsomeXx'sXinXit";
$count = ($string =~ tr/X//);
print "There are $count X characters in the string";
如果你只想查找单个字符,那么这种方法是可行的。但是,如果你想在一个更大的字符串中计算多个字符子串的数量,tr/// 是无法胜任的。你需要使用全局模式匹配将 while() 循环包裹起来。例如,我们可以计算负整数的数量:
$string = "-9 55 48 -2 23 -76 4 14 -44";
while ($string =~ /-\d+/g) { $count++ }
print "There are $count negative numbers in the string";
另一种版本在列表环境中使用全局匹配,然后将结果赋值给标量,产生匹配次数的计数。
$count = () = $string =~ /-\d+/g;
print $string =~ s/\./\./g;
试试这个:
my $string = "one.two.three.four";
my ($number) = scalar( @{[ $string=~/\./gi ]} );
对我来说,它返回3
。通过创建一个数组的引用,正则表达式在列表上下文中被求值,并且@{..}
取消引用了数组引用。
/(K..K)|(V.AK)/gi
),那么生成的数组可能会包含未定义的元素,这些元素会计入最终的计数。my $seq = "TSYCSKSNKRCRRKYGDDDDWWRSQYTTYCSCYTGKSGKTKGGDSCDAYYEAYGKSGKTKGGRNNR";
my $regex = '(K..K)|(V.AK)';
my $count = () = $seq =~ /$regex/gi;
print "$count\n";
my $seq = "TSYCSKSNKRCRRKYGDDDDWWRSQYTTYCSCYTGKSGKTKGGDSCDAYYEAYGKSGKTKGGRNNR";
my $regex = '(K..K)|(V.AK)';
my @count = $seq =~ /$regex/gi;
@count = grep defined, @count;
my $count = scalar @count;
print "$count\n";
那么这就给出了正确的答案是三。
Friedo的方法是:$a = () = $b =~ $c
。
但是,甚至可以进一步简化为只有($a) = $b =~ $c
,如下所示:
my ($matchcount) = $text =~ s/$findregex/ /gi;
getMatchCount()
,这样就不用担心它会改变传入的字符串。my ($matchcount) = $text =~ s/($findregex)/$1/gi;
另一种方式,
my $string = "one.two.three.four";
@s = split /\./,$string;
print scalar @s - 1;
my $count = 0;
my $pos = -1;
while (($pos = index($string, $match, $pos+1)) > -1) {
$count++;
}
经过基准测试,速度相当快
() = $string =~ /\./gi
,使匹配运算符在列表上下文中返回匹配结果。这类似于my @results = $string =~ /\./gi;
。接下来,my $number
部分是一个标量值。将列表上下文的结果分配给标量会返回其长度。这与my $count = @some_list
相同,它返回数组的长度。下面是我对此行为的另一种方式进行可视化的答案。 - Robert P