我正在读取这样的文件
1
one
2
two
3
three
three
three
four
five
5
在这篇文章中,我想检查序列one two three four five
,并打印三次出现的次数。
我的代码:
use warnings;
use strict;
open(tempp1,"<$temp1") or die "Could not open file $temp1: $!";
my $count = 0;
while(my $line=<tempp1>) {
if ($line eq "one") {
while(my $line=<tempp1>) {
if ($line eq "two") {
while(my $line=<tempp1>) {
if ($line eq "three") {
$count++;
while(my $line=<tempp1>) {
if ($line eq "four") {
while(my $line=<tempp1>) {
if ($line eq "five") {
last;
}}}}}}}}}}
print "$countn";
close tempp1;
输出正在打印:1如何更正?
问题是,当您应该同时查找three
和four
时,一旦遇到three
,就立即开始查找four
。
简单的答案是取代
while(my $line=<tempp1>) {
if ($line eq "three") {
$count++;
while(my $line=<tempp1>) {
if ($line eq "four") {
带有
while(my $line=<tempp1>) {
if ($line eq "three") {
$count++;
while(my $line=<tempp1>) {
if ($line eq "three") {
$count++;
}
elsif ($line eq "four") {
但目前尚不清楚这是否会产生预期的结果。考虑以下输入:
# Possible Sequence 1 Possible Sequence 2
# ------------------- -------------------
one # one one
two # two two
three # three three
three # three three
four # four
three # three
three # three
three # three
four # four
five # five five
# ------------------- -------------------
# 2 instances 5 instances
count
应该是2(找到four
时停止计数(还是5(尽可能大(?上述解决方案将返回2。
此外,请注意,您目前没有检查是否找到了four
和five
,但您建议这是必需的。
ikegami的回答中指出了它不起作用的原因。
但是,作为一种替代方案,您可以考虑使用基于正则表达式的解决方案。
例如:
use strict;
use warnings;
my $file_content;
do { # we use a do block to change the line terminator locally
local $/ = undef; # set line terminator as undef so we will read whole file
# when we would try to read a line
open my $fh, '<', 'file.txt' or die $!;
$file_content = <$fh>; # now it reads the whole file
close $fh or die $!;
};
if ($file_content =~ m/ ^ oneR twoR ((?:threeR)+) fourR five $ /ixm) {
print "Number of 'three's is: " . split m/R/, $1;
print "n";
} else {
die 'I could not find a valid sequence';
}
(注意,由于这将读取整个文件,因此您需要足够的内存来保存它(
然后您尝试使用以下regex:来匹配文件内容
m/
^ # start of line
oneR # literal 'one' + end of line character/s
twoR
((?:threeR)+) # One or more (+) "three" + end of line repetitions
# everything holded on a capturing group (outer parentheses)
fourR
five
$ # end of line (a character is not required)
/ixm # i = ignore case
# x = ignore whitespace and allows comments
# m = ^ and $ match begin and enf of line (instead of begin and end of string)
它有两个用途:
- 检查是否找到有效的1、2、3。。。,4、5序列
- 捕获3。。。,3部分
3。。。,3部分在第一个捕获组($1
(上捕获。然后按行分割内容,您拥有的行数就是three
的数
我会查找这样的行。
use strict;
use warnings;
use English;
my $counter=0;
my $threes = 0;
my @lines_to_match = qw(one two three four five);
open( my $fh , "<" , "file.txt") or die $OS_ERROR;
while ( my $line = readline($fh) )
{
if ( $counter < scalar(@lines_to_match) and $line =~m/$lines_to_match[$counter]/ )
{
$counter++;
}
$threes++ if $line =~m/three/;
}
close($fh);
print "counter = $counter - threes = $threesn";
您可以检查是否所有项目都与匹配
print "true" if $counter == scalar(@lines_to_match);
你也可以检查最后一场比赛是";三个";通过使用以下之一
$threes++ if $line =~m/three/ and $counter==3;
$threes++ if $line =~m/three/ and $line=~ m/$lines_to_match[$counter-1]/;