我能够找到类似但不完全相同的问题。如何在由未知字符分隔的同一行中多次匹配一个正则表达式?
例如,假设我想匹配模式HEY。我想要认识到以下所有内容:
HEY
嘿嘿
HEYxjfkdsjfkajHEY
所以我在那里算5个HEY。所以这是我的程序,它适用于除最后一个之外的所有内容:
open ( FH, $ARGV[0]);
while(<FH>)
{
foreach $w ( split )
{
if ($w =~ m/HEY/g)
{
$count++;
}
}
}
所以我的问题是如何替换foreach循环以便我可以识别未知配置中奇怪字符分隔的模式(如上例所示)?
修改
感谢迄今为止的出色回应。我只是意识到我需要另外一件事,我在下面的评论中提到了这一点。
但有一个问题:有没有办法保存匹配的条款?所以在我的情况下,是否有任何方法可以引用$ w(如果正则表达式更复杂,我想将它存储在具有出现次数的哈希值中)
所以,如果我匹配一个真正的正则表达式(比如一系列字母数字字符),并希望将其保存在哈希值中。
答案 0 :(得分:11)
一种方法是捕获字符串的所有匹配项,看看你得到了多少。像这样:
open (FH, $ARGV[0]);
while(my $w = <FH>) {
my @matches = $w =~ m/(HEY)/g;
my $count = scalar(@matches);
print "$count\t$w\n";
}
编辑:
是的,有!只需遍历所有匹配项,并使用捕获变量来增加哈希值中的计数:
my %hash;
open (FH, $ARGV[0]);
while (my $w = <FH>) {
foreach ($w =~ /(HEY)/g) {
$hash{$1}++;
}
}
答案 1 :(得分:5)
问题是你真的不想调用split()。它将事物分成单词,你会注意到你的最后一行只有一个“单词”(尽管你不会在字典中找到它)。一个词以白色空间为界,因此只是“除了空白之外的所有东西”。
你真正想要的是继续查看计算每个HEY的每一行,从每次离开的地方开始。这需要最后的/ g,但要继续寻找:
while(<>)
{
while (/HEY/g)
{
$count++;
}
}
print "$count\n";
当然,有不止一种方法可以做到这一点,但这很贴近你的榜样。其他人也会发布其他精彩的例子。向他们学习!
答案 2 :(得分:0)
上述答案都不适合我的类似问题。 1美元似乎没有变化(perl 5.16.3)所以$ hash {$ 1} ++将只计算第一场比赛n次。
要获得每个匹配,foreach需要分配一个局部变量,然后该变量将包含匹配变量。这是一个匹配并打印每个(数字)的小脚本。
#!/usr/bin/perl -w
use strict;
use warnings FATAL=>'all';
my (%procs);
while (<>) {
foreach my $proc ($_ =~ m/\((\d+)\)/g) {
$procs{$proc}++;
}
}
print join("\n",keys %procs) . "\n";
我正在使用它:
pstree -p | perl extract_numbers.pl | xargs -n 1 echo
(除了该管道中的一些相关过滤器)。任何模式捕获都应该起作用。