最近做实验时遇到这样的需求:统计某一 term 在 document 中的 TF (term frequency),即词频。借助 perl 完成,自然想到构造正则表达式进行匹配计数。目前可以找到的匹配计数方式有好几种:
假定 $string
是需要进行统计的字符串, $regex
是进行匹配的正则表达式。
方案一:
#method 1:my $count = 0;$count++ while ($string =~ m/$regex/g);
考虑到默认只返回第一次匹配,所以 /$regex/
最后需要加入 /g
,表示匹配所用情况。
方案二:
#method 2:my $count = ($string =~ s/$regex/$regex/g);
这里通过自身替换来获得最终替换的次数,也等于匹配计数。
方案三:
#method 3:$count = () = $string =~ /$regex/g;
这里有一点小 trick ,$string =~ /$regex/g
会返回一个包含所有匹配的 scalar 变量 (可以理解为一维数组),通过 ()
构造匿名 scalar 变量,然后转换为普通变量,而 perl 对于这类转换的结果是 scalar 的长度,即匹配计数,同样达到了目的。
相比之下,方案一最为直观,缺点是用到了两行代码。方案三最为隐晦,却是最为 perl 程序员欢迎的 terse style 。刚入门时会觉得方案一更好,但是日后会发现方案三更好。这也是为什么外界将 perl 评为最生涩语言的原因吧。