【问题标题】:perl: More concise way to branch based on whether split succeeded?perl:基于拆分是否成功的更简洁的分支方式?
【发布时间】:2017-04-17 22:26:41
【问题描述】:

我知道 split 返回解析的字段数,如果它分配给一个标量;如果分配给数组,则返回一个数组。

有没有办法检查一行是否成功解析而不必调用 split 两次(一次检查解析了多少字段,如果解析了正确数量的字段,第二次返回字段一个数组)?

foreach (@lines) {

  if ( split ) {
    my ($ipaddr, $hostname) = split;
  }

}

.. 我需要检查拆分是否成功,以避免以后对 $ipaddr 和 $hostname 的未初始化引用。看来我应该能够将两个调用合并为一个调用。

【问题讨论】:

  • 请将您的用户名更改为我们可以键入的名称,而无需一次检查每个字符。
  • @Borodin 有标签自动完成功能。这对你不起作用吗?这个至少选择了一个名字和一张图片,而不仅仅是user123123123。 :)
  • @Simbabque:不在我大部分时间都必须使用的平板电脑上。无论如何,我认为选择一个不可发音的用户名是不礼貌的。 123123123我至少可以发音和打字,而无需不断地回溯。我想知道为什么有人想要将 SO 分配的默认用户名 user9999999 更改为这样的名称。
  • @B 关于平板电脑的要点。当我键入 @ 时,我的手机键盘的自动完成功能有 @Borodin@ikegami 和其他几个。 (它还有一堆 Ingress 屏幕名称,因为它在其聊天中使用相同的语法)。我所做的只是输入第一个字母。如果只有一个人的名字以它开头,这足以让 SO 突出显示。

标签: arrays perl parsing split


【解决方案1】:

当然:

foreach (@lines) {
  if (2 == (my ($ipaddr, $hostname) = split)) {
    # Got exactly two fields
  }
}

所以如果你只是想跳过坏行,你可以简单地使用:

foreach (@lines) {
  2 == (my ($ipaddr, $hostname) = split)
    or next;

  # Got exactly two fields
}

不要忘记先从行中删除尾随空格(例如使用 chomp 删除换行符),否则会弄乱您的字段计数。

如果可能有更多字段,您可以将== 更改为<=

【讨论】:

  • 这依赖于在标量上下文中使用列表赋值运算符,它返回其 RHS 评估的值的数量。 Mini-Tutorial: Scalar vs List Assignment Operator 解释了两个不同的赋值运算符以及它们在每个上下文中返回的内容。
【解决方案2】:

我想我更喜欢正则表达式匹配:

for ( @lines ) {

    next unless my ($ipaddr, $hostname) = /(\S+)\s+(\S+)/;

    # use $ipaddr & $hostname

}

这与原来的不同之处在于,如果找到超过两个非空格子字符串,它将成功,但如果需要,修复很简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-24
    • 2011-11-05
    相关资源
    最近更新 更多