【问题标题】:How to take in multiple arguments如何接受多个参数
【发布时间】:2023-01-12 06:09:19
【问题描述】:

我有一个程序可以计算给定的天数、小时数、分钟数或秒数,但它只能接受 1 个参数,例如“1d”= 86400 秒。

现在我想让它计算何时给它类似“1d 3h 16m 2s”并将其传递给秒数。同样,当输入错误时,我希望它告诉用户类似“错误输入”的信息。

我怎么能让那个工作?

这是我到目前为止得到的代码,现在我需要将它修改为新的设置seconds calculator

【问题讨论】:

标签: php arrays switch-statement argv


【解决方案1】:

为了匹配多个单位时间,我使用了preg_match_all() 函数,然后为每个时间单位使用一个开关迭代。计算每个单位的秒数并求和。

<?php
   $input = '1d 3h 16m 2s';
    $seconds = 0;
    $pattern = "/(d+)(d|h|m|s)/";

    preg_match_all($pattern, $input, $matches);

    for ($i = 0; $i < count($matches[0]); $i++) {
        switch ($matches[2][$i]) {
            case "d":
                $seconds += (int)$matches[1][$i] * 86400;
                break;
            case "h":
                $seconds += (int)$matches[1][$i] * 3600;
                break;
            case "m":
                $seconds += (int)$matches[1][$i] * 60;
                break;
            case "s":
                $seconds += (int)$matches[1][$i];
                break;
            default:
                echo "Invalid input format";
                return;
        }
    }

    echo $seconds;

PHP在线:https://onlinephp.io/c/f7d8c

【讨论】:

    【解决方案2】:

    假设您没有任何更高的单位要解析,并且这些单位始终按大端顺序排列,您可以使用单个正则表达式模式来解析字符串中的所有数据,然后使用简单的算术来计算秒数。

    正则表达式将尝试捕获每个可选单元的数量。即使给定的单元不存在,matches 数组仍将保持位置,以便元素始终一致地放置。子模式相当重复,因此如果需要,这将使扩展/减少更容易。

    代码:(Demo

    preg_match('/^(?:(d+)d ?)?(?:(d+)h ?)?(?:(d+)m ?)?(?:(d+)s)?$/', $input, $m);
    echo ((int) ($m[1] ?? 0) * 86400)
         + ((int) ($m[2] ?? 0) * 3600)
         + ((int) ($m[3] ?? 0) * 60)
         + (int) ($m[4] ?? 0) . " seconds";
    

    如果您的输入数据具有一致的格式并且始终包含每个单位,那么该过程会简单得多,因为sscanf() 可以将数字直接解析为整数。 (Demo)

    sscanf($input, '%dd %dh %dm %ds', $d, $h, $m, $s);
    echo $d * 86400 + $h * 3600 + $m * 60 + $s;
    

    如果不能保证单元存在或可能以任何顺序存在,您可以使用此函数式样式的 sn-p 来解析表达式。它隔离每个数字单元对,利用查找数组将数字乘以适当的因子,然后对计算求和。 (Demo)

    define('UNIT_TO_SECONDS', ['d' => 86400, 'h' => 3600, 'm' => 60, 's' => 1]);
    
    echo array_reduce(
             preg_match_all('/(d+)([dhms])/', $input, $m, PREG_SET_ORDER) ? $m : [],
             fn($sum, $parts) => $sum + UNIT_TO_SECONDS[$parts[2]] * (int) $parts[1],
             0 // initialize $sum with 0 value
         );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-19
      • 2020-07-20
      • 2020-02-17
      • 1970-01-01
      • 2021-10-16
      相关资源
      最近更新 更多