【问题标题】:using a counter variable in Perl hash key names在 Perl 哈希键名中使用计数器变量
【发布时间】:2012-02-29 18:48:52
【问题描述】:

我有一堆 HTML 表单字段数据作为散列传入,其中每个字段名称成为键,字段值是散列值...您的标准 CGI 模块输出来自:

my $query = new CGI;
my %formdata = $query->Vars;

这次我正在处理多个表单域的集合,每个域都有一个数字后缀(“name1”“name2”...“size1”“size2”等)。有没有比这更好的方法来使用计数器按数字顺序循环遍历这些组?

for (my $i = 1; $i < 10; $i++) {
  print "  Name $i: " . $formdata{"name$i"} . "\n";
  print "  Size $i: " . $formdata{"size$i"} . "\n";
}

...这还不错,但有更简单的语法吗? IE。像这样(但这不起作用 - 没有包或对象引用就无法调用方法“名称”):

  print "  Name $i: $formdata{name$i}\n";

【问题讨论】:

    标签: perl variables hash


    【解决方案1】:

    明显的解决方案不起作用:

      print "  Name $i: $formdata{"name$i"}\n";
    

    但可以通过用 qq 运算符(qq{...}qq(...)qq/.../ 或任何你喜欢的)替换任一组实际双引号 "..." 来修复:

      print qq{  Name $i: $formdata{"name$i"}\n};
    

    "Quote and Quote-like Operators" in the perlop man-page

    【讨论】:

    • 谢谢,我不确定是否还有其他方法,因为 print "name $i $formdata{$varname}";当 entire 键名被制作成字符串变量时,似乎无需双重插值即可工作......
    • @Wick:我认为你误解了为什么"$formdata{$varname}" 有效。它实际上没有插入$varname;它只需要$varname 成为一个普通的字符串表达式——它就是——并使用该表达式的值作为键。请注意,即使在双引号之外,您也可以写 $formdata{$varname};相反,您甚至可以在双引号内写$formdata{'name' . $i} 之类的内容。那有意义吗?所以qq{$formdata{"name$i"}} 没有做“双插值”;它只插入一次$i,并插入例如$formdata{'name6'} 恰好一次。
    • 啊哈,谢谢,这解释了很多,非常清楚。我真的很感激!
    【解决方案2】:

    我通常通过根据表单名称前缀制作一个键列表来做这种事情。例如,

    my @numbers = sort map { /name(\d+)/ } keys %formdata;
    foreach my $num( @numbers ) { 
        print "  Name $num: ", $formdata{ 'name' . $num }, "\n";
        ...
    }
    

    这具有适用于任意数量的表单元素的优势。

    【讨论】:

    • sort,默认情况下使用 ASCIIbetical 字符串比较。您必须指的是sort { $a &lt;=&gt; $b } map ...,而不是简单的sort map ...。另外,我认为您应该通过编写/^name(\d+)\z/ 而不是/name(\d+)/,将您的正则表达式锚定到字符串开始和字符串结束。
    • 整洁,似乎是获取最大字段的好方法。绝对是在脚本中硬编码循环最大值的改进,以防万一表单发生变化并且有人忘记更新脚本。不完全是我所追求的,但也很酷!谢谢
    【解决方案3】:

    如果您想在由" 分隔的字符串中使用",请将其转义。

    print "  Name $i: $formdata{\"name$i\"}\n";
    

    或者更改分隔符。

    print qq{  Name $i: $formdata{"name$i"}\n};
    

    或者避免使用"

    print "  Name $i: $formdata{qq{name$i}}\n";
    print "  Name $i: $formdata{'name'.$i}\n";
    printf "  Name %s: %s\n", $i, $formdata{"name$i"};
    print "  Name $i: " . $formdata{"name$i"} . "\n";
    

    【讨论】:

    • 太棒了,谢谢。 ruakh 在你的回答和跟进 cmets 中得到了这个,大约在你进来前一个小时,但除此之外,我认为你的回答也绝对正确,我很欣赏所有的例子。祝你好运
    猜你喜欢
    • 1970-01-01
    • 2013-08-26
    • 2015-08-01
    • 1970-01-01
    • 2015-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    相关资源
    最近更新 更多