匹配多个结果perl

时间:2014-07-15 22:16:54

标签: perl while-loop string-matching

我有一个简单的问题。假设我有一个名称列表,其中一些人缺少“帐号”。我将举一个由管道“|”分隔的例子。 “_”将代表空白。

Jim|1

John|_

Joe|2

John|_

John|_

JEff_234

JEff_298

.....如果客户缺少身份证号码,那么列表会继续增加10,000行。

我的目标是使用每个适当的ID填充空白,John例如需要ID。

幸运的是,我们有一个主列表可以将名称引用到适当的ID,但就像我说的那样,由于行数很大,手动填充空白需要花费很长时间。

问题在于John或其他任何人可能拥有多个ID。

我所拥有的脚本将仅使用给定的第一个ID填充“John”。检查下面的示例。

LINE: while (<>) {

if (/(John)/gi){print $_ = $1."|"."ID_NUMBER_5"."\n"; print STDOUT "match!!!!\n"; next};
if (/(John)/gi){print $_ = $1."|"."ID_NUMBER_6"."\n"; print STDOUT "match!!!!\n"; next};
if (/(John)/gi){print $_ = $1."|"."ID_NUMBER_7"."\n"; print STDOUT "match!!!!\n"; next};

    print;

}

我得到的结果是:

Jim|1

John|ID_NUMBER_5

Joe|2

John|ID_NUMBER_5

John|ID_NUMBER_5

JEff_234

JEff_298

因此,如果约翰有多个“帐户”或“ids”,这将无效。

我想要的结果是:

Jim|1

John|ID_NUMBER_5

Joe|2

John|ID_NUMBER_6

John|ID_NUMBER_7

JEff_234

JEff_298

有任何想法或适当的方法来解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

将帐户保存在列表的哈希中。在每行查找匹配时使用哈希的键。每次找到匹配项并且仍有帐户列表条目从相应列表中移出一个。

my %accountMap = ("John", ["ID_NUMBER_5", "ID_NUMBER_6", "ID_NUMBER_7"],
                  "Bob", ["ID_NUMBER_8"]);

LINE: while (<>) {
  foreach $acctName (keys %accountMap) {
    if (/($acctName)/gi && $accountMap{$acctName} && scalar @{$accountMap{$acctName}} > 0) {
      my @accounts = @{$accountMap{$acctName}};
      my $account = shift @accounts;
      $accountMap{$acctName} = [@accounts];
      print $_ = $1."|". $account ."\n";
      next LINE;
    }
  }
  print;
}