【问题标题】:Assign resulting regex named groups hash to a hash value将生成的正则表达式命名组哈希分配给哈希值
【发布时间】:2018-04-03 18:31:46
【问题描述】:

我有这个带有用户数据的字符串:

"1111|John|Smith|32\n2222|Sam|Adams|25\n3333|Chris|Stevens|30\n"

我正在尝试使用正则表达式读取它并创建这样的哈希(使用 JSON 表示法使其易于理解):

{
    "1111": {
        "IdNumber" : "1111",
        "Name" : "John",
        "LastName" : "Smith",
        "Age" : "32"
    },
    "2222": {
        "IdNumber" : "2222",
        "Name" : "Sam",
        "LastName" : "Adams",
        "Age" : "25"
    },
    "3333": {
        "IdNumber" : "3333",
        "Name" : "Chris",
        "LastName" : "Stevens",
        "Age" : "30"
    },
}

父哈希必须以用户的 id 作为键,值将是包含所有用户数据的子哈希。

我尝试使用命名组直接评估生成的 $+ 哈希:

use strict;
use warnings;

use Data::Dumper;

my $str = "1111|John|Smith|32\n2222|Sam|Adams|25\n3333|Chris|Stevens|30\n";

my %users;

while ($str =~ /(?<IdNumber>.*?)\|(?<Name>.*?)\|(?<LastName>.*?)\|(?<Age>.*?)/g){
    $users{$+{IdNumber}} = %+;
}

print Dumper %users;

但是我得到了这个结果:

$VAR1 = '1111';
$VAR2 = 4;
$VAR3 = '3333';
$VAR4 = 4;
$VAR5 = '2222';
$VAR6 = 4;

在我看来,子哈希正在转换为标量,但我找不到错误。

你有什么想法吗?谢谢。

【问题讨论】:

  • 建议:首先在\n 上拆分数据,然后在| 上拆分数据,而不是使用正则表达式

标签: regex perl hashmap regex-group


【解决方案1】:
open(my $fh, '<', \$str);

my %users;
while (<$fh>) {
   chomp;
   my %row;
   @row{qw( IdNumber Name LastName Age )} = split /\|/;
   $users{ $row{IdNumber} } = \%row;
}

或者,

my %users;
for (split /^/m, $str) {
   chomp;
   my %row;
   @row{qw( IdNumber Name LastName Age )} = split /\|/;
   $users{ $row{IdNumber} } = \%row;
}

或者,因为我们可以放心地忽略训练空行,

my %users;
for (split /\n/, $str) {
   my %row;
   @row{qw( IdNumber Name LastName Age )} = split /\|/;
   $users{ $row{IdNumber} } = \%row;
}

【讨论】:

  • 谢谢,这很好用。你知道 split 与 regex 相比是否具有良好的性能吗?
  • 这是一个相当奇怪的问题,因为它的第一个参数是正则表达式模式。更奇怪的是,答案是它比正则表达式匹配更快。
猜你喜欢
  • 2018-01-12
  • 1970-01-01
  • 2012-04-13
  • 2011-07-08
  • 2016-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多