【问题标题】:How do I parse an array in perl that contains subarrays?如何在 perl 中解析包含子数组的数组?
【发布时间】:2020-01-11 09:58:09
【问题描述】:

让我先说我是 perl 的新手。

我需要修改邮件系统的规则。我可以将规则作为数组访问,并且我相信该数组包含子数组。我需要修改一个特定元素并保留其余元素。我的问题是我对数组类型到底是什么以及如何始终如一地访问元素感到困惑。

可能有不止一组规则,但我只对处理优先级为“1”的规则感兴趣,即$Rule[0]。在$Rule[3] 内我需要解析地址。

use strict;
use Data::Dumper qw(Dumper);

my $Rules=$cli->GetAccountMailRules($account);

print Dumper \@$Rules;

    foreach my $Rule (@$Rules) {
      if($Rule->[0]=~/1/) {
        my $pri=$Rule->[0];
        my $type=$Rule->[1];
        my $auto=$Rule->[2];
        my $actions=$Rule->[3];
        my $action1;
        my $auto1;
        my $auto2;
        my @newRule;
        my $oldDest;
        print "\n";

        print "Priority:\n";
        print Dumper \$pri;
        print "\n";

        print "Rule Type:\n";
        print Dumper \$type;
        print "\n";

        print "Forward Auto?:\n";
        print Dumper \$auto;
        print "\n";

        print "Actions:\n";
        print Dumper \$actions;
        print "\n";

        foreach my $ax (@$actions) {
          $action1=$ax->[0];
          $oldDest=$ax->[1];
        } 

        my @addresses=split /[;,]|\\e/, $oldDest;
        my @dests = grep(/corp.com|corp1.com|corp2.com|corp3.com/, @addresses);
        my $newDest = join(",", @dests);
        if (@$auto) {
          foreach my $au (@$auto) {
            $auto1=$au->[0];
            $auto2=$au->[1];    
          }
          @newRule=(
            [ $pri, $type,
            [[$auto1,$auto2]],
            [[$action1,$newDest]]
            ]
            );
        } else {
          @newRule=(
            [ $pri, $type,
            [],
            [[$action1,$newDest]]
            ]
            );
        }
      }  
    }
}

这样输出:

# perl removeRules.pl
$VAR1 = [
          [
            '1',
            '#Redirect',
            [
              [
                'Human Generated',
                '---'
              ]
            ],
            [
              [
                'Mirror to',
                'test10@corp.com\\etest10@gmail.com\\etest10@corp1.com'
              ]
            ]
          ]
        ];

Priority:
$VAR1 = \'1';

Rule Type:
$VAR1 = \'#Redirect';

Forward Auto?:
$VAR1 = \[
            [
              'Human Generated',
              '---'
            ]
          ];

Actions:
$VAR1 = \[
            [
              'Mirror to',
              'test10@corp.com\\etest10@gmail.com\\etest10@corp1.com'
            ]
          ];

我遇到的问题是$actions 中有一个选项可以在转发后丢弃电子邮件,这会将新元素(或子数组?)引入$actions

# perl removeRules.pl
$VAR1 = [
          [
            '1',
            '#Redirect',
            [
              [
                'Human Generated',
                '---'
              ]
            ],
            [
              [
                'Mirror to',
                'test10@corp.com\\etest10@gmail.com\\etest10@corp1.com'
              ],
              [              <---- Begin new elements
                'Discard',   
                '---'
              ]              <---- End new elements
            ]
          ]
        ];

Priority:
$VAR1 = \'1';

Rule Type:
$VAR1 = \'#Redirect';

Forward Auto?:
$VAR1 = \[
            [
              'Human Generated',
              '---'
            ]
          ];

Actions:
$VAR1 = \[
            [
              'Mirror to',
              'test10@corp.com\\etest10@gmail.com\\etest10@corp1.com'
            ],
            [
              'Discard',
              '---'
            ]
          ];

我尝试测试它们是否可以在 $actions 中作为附加元素引用,但它会抛出索引。

my $action2;
my $action3;

print "Actions:\n";
print Dumper \$actions;
print "\n";

foreach my $ax (@$actions) {
  $action1=$ax->[0];
  $oldDest=$ax->[1];
  $action2=$ax->[2];
  $action3=$ax->[3];
} 

print "  action1 $action1\n";
print "  oldDest $oldDest\n";
print "  action2 $action2\n";
print "  action3 $action3\n";

输出:

Actions:
$VAR1 = \[
            [
              'Mirror to',
              'test10@corp.com\\etest10@gmail.com\\etest10@corp1.com'
            ],
            [
              'Discard',
              '---'
            ]
          ];

  action1 Discard
  oldDest ---
Use of uninitialized value $action2 in concatenation (.) or string at removeRules.pl line 107, <GEN0> line 4.
  action2
Use of uninitialized value $action3 in concatenation (.) or string at removeRules.pl line 108, <GEN0> line 4.
  action3

提前谢谢你。

【问题讨论】:

    标签: arrays perl scalar


    【解决方案1】:

    使用这个:

            [
              [
                'Mirror to',
                'test10@corp.com\\etest10@gmail.com\\etest10@corp1.com'
              ],
              [
                'Discard',   
                '---'
              ]
            ]
    

    这是对包含两项的数组(外部[..])的引用。每一项都是对数组的引用。

    第一项(外部数组引用的位置 0)是

              [
                'Mirror to',
                'test10@corp.com\\etest10@gmail.com\\etest10@corp1.com'
              ],
    

    第二个(位置 1)是:

              [
                'Discard',   
                '---'
              ]
    

    如果$ractions是这个外层数组,那么上面两项分别在$ractions-&gt;[0]$ractions-&gt;[1]下。

    由于它们都是数组引用,您可以使用相同的构造或使用 Perl 属性访问它们的项目,您可以删除第二个数组。

    简而言之:

    • 'Mirror to' 可以通过$ractions-&gt;[0]-&gt;[0] 或更短的$ractions-&gt;[0][0] 访问
    • 'test10@corp.com\etest10@gmail.com\etest10@corp1.com'可以通过$ractions-&gt;[0]-&gt;[1]访问
    • 'Discard' 可以通过$ractions-&gt;[1]-&gt;[0] 访问
    • '---'可以通过$ractions-&gt;[1]-&gt;[1]访问

    但请注意,$VAR1 = \[ 表明您对引用有引用。所以你需要一个额外的去引用步骤:

      DB<1> use Data::Dumper;
    
      DB<2> @a=(1,2)
    
      DB<3> print Data::Dumper::Dumper(@a);
    $VAR1 = 1;
    $VAR2 = 2;
    
      DB<4> print Data::Dumper::Dumper(\@a);
    $VAR1 = [
              1,
              2
            ];
    
      DB<5> print Data::Dumper::Dumper(\\@a);
    $VAR1 = \[
                1,
                2
              ];
    

    PS:当你需要混淆域名时,不要使用corp.com 或类似的东西。请参阅 RFC2606 或 TL 中的指南;DR:使用 example.com

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-16
      • 2023-04-02
      • 1970-01-01
      • 2016-03-13
      • 2011-12-19
      • 2016-08-02
      相关资源
      最近更新 更多