如何正则表达式匹配A / B / C ...?(How to regex match a/b/c …

2019-09-28 03:22发布

如果我有像下面的阵列,其中,所述元素的顺序是随机的,也有在每个元件可以多少层没有限制。 这里只显示3个级别。 ab ,和c

我希望能够解析这样的阵列,并且将结果存储在哈希像这样的哈希,当只有3个级别

$VAR1 = {
          'a' => {
                   'b' => 'c'
                 }
        };

我的问题是如何写这个正则表达式,因为第一级不具有/末,并且因为元素的顺序是随机的,如果a/b/c已经在哈希插入,然后元素a不应该为删除键的哈希值a

所以如何解决这样的问题?

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my @ar = ("a", "a/b", "a/b/c");
my %h = ();

foreach my $a (@ar) {
}

Answer 1:

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use Data::Diver 'DiveRef';

my @array = ("a", "a/b", "a/b/c");
my %hash = ();

foreach my $element (@array) {
    DiveRef( \%hash, \( split /\//, $element ) );
}

通常你会分配给或修改DiveRef返回的标量引用(或指定DiveVal的结果),但在这里你只是想确保键存在。

\(...)变为由分返回到标引用的列表,它告诉数据::潜水员这些总是会被哈希键,不可能数组索引,如果他们是数字列表。



Answer 2:

要得到

"a"                 => $tree = "a";
"a", "a/b"          => $tree = { "a" => "b" };
"a", "a/b", "a/b/c" => $tree = { "a" => { "b" => "c" } };
"a", "a/b", "a/c"   => $tree = { "a" => { "b" => undef, "c" => undef } };

码:

my $tree;
for ("a", "a/b", "a/b/c") {
   my @keys = split qr{/};
   my $val = pop(@keys);

   my $p = \$tree;
   while (@keys) {
      my $key = shift(@keys);
      $$p = { $$p => undef } if !ref($$p);
      $p = \( ($$p)->{$key} );
   }

   if (defined($$p)) {
      $$p = { $$p => undef } if !ref($$p);
      ($$p)->{$val} = undef;
   } else {
      $$p = $val;
   }
}

但是,这不是一个很好的数据结构,因为你需要使用ref浏览它。 相反,我建议

"a"                 => $tree = { "a" => undef };
"a", "a/b"          => $tree = { "a" => { "b" => undef } };
"a", "a/b", "a/b/c" => $tree = { "a" => { "b" => { "c" => undef } } };
"a", "a/b", "a/c"   => $tree = { "a" => { "b" => undef, "c" => undef } };

码:

my $tree;
for ("a", "a/b", "a/b/c") {
   my $p = \$tree;
   $p = \( ($$p)->{$_} ) for split qr{/};
}

看到它是多么简单建立这个数据结构? 当您尝试浏览它,你会得到类似的好处。


请注意,您可以使用数据::潜水员创建第二个数据结构(虽然我记得它是慢得多)。

use Data::Diver qw( DiveRef );

my $tree;
for ("a", "a/b", "a/b/c") {
   DiveRef($tree //= {}, \split(qr{/}));
}


Answer 3:

一个例子:

my @ar = ("a", "a/b", "a/b/c");
my %h;

for (@ar) {
    my $levels = split /\//;

    for (my $i = 0; $i <= $#levels; $i++) {
        # How ever you want to set-up your hash of hashes
        # But each for loop iteration would give you a "level" of input
    }
}


文章来源: How to regex match a/b/c …?
标签: regex perl hash