如何将特定模式与if条件匹配

时间:2013-05-01 12:04:29

标签: perl pattern-matching

我的文字档案:

Name: mak
Place: ynr
Age: 22
------------- 
Name: john
Place: kkr
Age: 21
------------- 
Name: mak
Place: knl
Age: 23
-------------

我正在做的是:

open(FILE, "path to file") or die "";
$check="mak";
@arr=<FILE>
for(@arr)
{
    if ($_=/Name:\s(.*)/)
    {
        $a=$1;
        if($a eq $check)
        {
            print "matched name"
        }
        #now i want if "mak" is matched then after that it should match the age and store it one variable and then compare it with other matched age with same name
    }
}

我想首先得到这个名字,如果它匹配为“mak”,那么我需要检查年龄并比较年龄。

3 个答案:

答案 0 :(得分:4)

您的文件格式可以描述如下:

  • 通过水平条将多个记录彼此分开
  • 每条记录都有多个名称 - 值对,每个记录都在各自的行中

输入记录分隔符$/可以设置为任意字符串,因此我们可以

local $/ = "-------------\n";

现在,每个readline操作将返回一条记录。 chomp将删除分隔符。

从记录中获取字段就像

一样简单
my %fields = map split(/:\s*/, $_, 2), split /\n/, $record;

我们可以将它结合起来一次检查一条记录:

use strict; use warnings;

my $check = shift @ARGV;

local $/ = "-------------\n";
while (<>) {
  chomp;
  my %fields = map split(/:\s*/, $_, 2), split /\n/, $_;
  if ($fields{Name} eq $check) {
    # do something
  }
}

这将在perl the-script.pl mak file.txt等命令行上调用。

答案 1 :(得分:2)

有很多方法可以解决这个问题,但这里有一个我喜欢它的简洁方法:

use File::Slurp;
@records=split('---',read_file('file.txt'))

例如,$records[0]包含:

Name: mak
Place: ynr
Age: 22

@records中会有“垃圾”条目,因为分割模式并不完美,但这并不重要。现在,您可以迭代@records找到您需要的那个。

答案 2 :(得分:0)

这是另一种选择:

use strict;
use warnings;

my @rec;
while (<>) {
    push @rec, $1 if /^(?:Name|Place|Age):\s+(.+)/;
    next unless @rec == 3;

    print "@rec\n" if $rec[0] eq 'mak' and $rec[2] == 23;

    undef @rec;
}

用法:perl script.pl inFile [>outFile]

最后一个可选参数将输出重定向到文件。

数据集输出:

mak knl 23

当读取文件行时,正则表达式会查找以Name,Age或Place开头的行,然后捕获冒号后面的所有空格。 $1中捕获的值push@rec,下一行为unless,已经处理了三条记录行。如果@rec的元素零等于“mak”而元素2等于23,则打印记录的值。最后,@recundef,因此它已准备就绪,可用于下一条记录。

希望这有帮助!