Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这种Perl行为可以通过开关/案例或给定/何时进行模拟吗?_Perl - Fatal编程技术网

这种Perl行为可以通过开关/案例或给定/何时进行模拟吗?

这种Perl行为可以通过开关/案例或给定/何时进行模拟吗?,perl,Perl,我想知道是否有人对改进下面的代码(如果可能的话)有什么建议,这样它就不需要重复(my@a=$time=~…),可能使用case/switch或given/when或其他一些我缺少的想法 my $time = '12:59pm'; if( my @a = $time =~ m/^(\d\d?)(am|pm)$/ ) { tell_time( $a[0], 0, $a[1] ) } if( my @a = $time =~ m/^(\d\d?):(\d\d)(am|pm)$/ ) {

我想知道是否有人对改进下面的代码(如果可能的话)有什么建议,这样它就不需要重复(my@a=$time=~…),可能使用case/switch或given/when或其他一些我缺少的想法

my $time = '12:59pm';

if( my @a = $time =~ m/^(\d\d?)(am|pm)$/ )        { tell_time( $a[0], 0, $a[1] ) }
if( my @a = $time =~ m/^(\d\d?):(\d\d)(am|pm)$/ ) { tell_time( @a ) }
if( my @a = $time =~ m/^(\d\d?):(\d\d)$/ )        { tell_time( @a ) }

sub tell_time
{
    my $hour    = shift;
    my $minute  = shift || '00';
    my $ampm    = shift || ( $hour > 12 ) ? 'pm' : 'am';

    print "Hour: $hour, Minute: $minute, AMPM: $ampm\n";
}
我尝试过使用Switch和5.10 given/when,但似乎无法执行以下操作:

given( $time )
{
    when( /^(\d\d?)(am|pm)$/ )        { tell_time( $_[0], 0, $_[1] ) }
    when( /^(\d\d?):(\d\d)(am|pm)$/ ) { tell_time( @_ ) }
    when( /^(\d\d?):(\d\d)$/ )        { tell_time( @_ ) }
}
这不起作用,因为"似乎在存储$time

还要注意,我对问题的语法比对代码解决的问题更感兴趣。我很清楚,我可以使用Time::ParseDate来计算格式类似于时间或日期的字符串的各个部分。

您的正则表达式使用
()
来提取匹配项,但您不必将它们存储在数组中。如果需要,它们存储在
$1
$2
$3
中,依此类推。瞧:

given( $time )
{
    when( /^(\d\d?)(am|pm)$/ )        { tell_time( $1, 0, $2 ) }
    when( /^(\d\d?):(\d\d)(am|pm)$/ ) { tell_time( $1, $2, $3 ) }
    when( /^(\d\d?):(\d\d)$/ )        { tell_time( $1, $2 ) }
}
做我认为你想做的事

如果您想添加到语法中,我会编写
tell_time()
,将时间作为字符串,让函数自己解析结果,而不是让代码的用户自己解析。或者,您可以使用这个
given()
块作为一个新函数的开始,该函数可以解析时间字符串,并将其正确地传递给
tell\u time()
。但那只是我。我不知道你需要你的代码做什么,所以一定要去做。

你的正则表达式使用
()
来提取匹配项,但你不必将它们存储在数组中。如果需要,它们存储在
$1
$2
$3
中,依此类推。瞧:

given( $time )
{
    when( /^(\d\d?)(am|pm)$/ )        { tell_time( $1, 0, $2 ) }
    when( /^(\d\d?):(\d\d)(am|pm)$/ ) { tell_time( $1, $2, $3 ) }
    when( /^(\d\d?):(\d\d)$/ )        { tell_time( $1, $2 ) }
}
做我认为你想做的事


如果您想添加到语法中,我会编写
tell_time()
,将时间作为字符串,让函数自己解析结果,而不是让代码的用户自己解析。或者,您可以使用这个
given()
块作为一个新函数的开始,该函数可以解析时间字符串,并将其正确地传递给
tell\u time()
。但那只是我。我不知道你需要你的代码做什么,所以想尽一切办法去做。

好吧,不使用switch/case,我只使用一个正则表达式来捕获所有的变化

#!/usr/bin/perl

tell_time ("12:59am");    # matches time format 1
tell_time ("2:59pm");     # matches time format 1
tell_time ("12am");       # matches time format 2
tell_time ("12:59");      # matches time format 3
tell_time ("14:59");      # matches time format 3
tell_time ("12:59:59am"); # produces no output, does not match any known time formats.

sub tell_time
{
    my $timearg = shift;

    # note: (?: ... ) creates a non-capturing group, which is not reflected in 
    # the returned array.
    my ($hour , $minute, $ampm) = ( $timearg =~ m/^(\d\d?)(?::(\d\d?))?(am|pm)?$/ ) ;

    # only continue if we captured all required fields (i.e. hour)
    if($hour)
    {
        # set default values for optional fields (i.e. minute, ampm) if necessary
        $minute ||=  '00';
        $ampm ||=  ( $hour > 12 ) ? 'pm' : 'am';

        print "Hour: $hour, Minute: $minute, AMPM: $ampm\n";
    }

}

如果有必要,我可以进一步解释,但我认为如果你能阅读perl,它应该清楚它在做什么……

好吧,不使用switch/case,我只使用一个正则表达式来捕获所有的变化

#!/usr/bin/perl

tell_time ("12:59am");    # matches time format 1
tell_time ("2:59pm");     # matches time format 1
tell_time ("12am");       # matches time format 2
tell_time ("12:59");      # matches time format 3
tell_time ("14:59");      # matches time format 3
tell_time ("12:59:59am"); # produces no output, does not match any known time formats.

sub tell_time
{
    my $timearg = shift;

    # note: (?: ... ) creates a non-capturing group, which is not reflected in 
    # the returned array.
    my ($hour , $minute, $ampm) = ( $timearg =~ m/^(\d\d?)(?::(\d\d?))?(am|pm)?$/ ) ;

    # only continue if we captured all required fields (i.e. hour)
    if($hour)
    {
        # set default values for optional fields (i.e. minute, ampm) if necessary
        $minute ||=  '00';
        $ampm ||=  ( $hour > 12 ) ? 'pm' : 'am';

        print "Hour: $hour, Minute: $minute, AMPM: $ampm\n";
    }

}

如果有必要,我可以进一步解释它,但我认为如果你能阅读perl,那么应该清楚它在做什么……

Chris Lutz已经介绍了使用perl 5.10的开关语法。为了获得Perl版本,可以使用循环别名来模拟:

for ($time) {
  /^(\d\d?)(am|pm)$/        && do { tell_time( $1, 0, $2 );  last };
  /^(\d\d?):(\d\d)(am|pm)$/ && do { tell_time( $1, $2, $3 ); last };
  /^(\d\d?):(\d\d)$/        && do { tell_time( $1, $2 );     last };
}

Chris Lutz已经使用Perl 5.10介绍了开关语法。为了获得Perl版本,可以使用循环别名来模拟:

for ($time) {
  /^(\d\d?)(am|pm)$/        && do { tell_time( $1, 0, $2 );  last };
  /^(\d\d?):(\d\d)(am|pm)$/ && do { tell_time( $1, $2, $3 ); last };
  /^(\d\d?):(\d\d)$/        && do { tell_time( $1, $2 );     last };
}

由于您使用的是5.10,您最好在正则表达式中使用:

#!/usr/bin/perl

use 5.010;
use strict;
use warnings;

my $hour24   = qr/(?<hour>[1-9]|1[0-9]|2[0-3])/;
my $hour12   = qr/(?<hour>[1-9]|1[0-2])/;
my $minute   = qr/(?<minute>[0-5][0-9])/;
my $meridiem = qr/(?<meridiem>am|AM|pm|PM)/;

for my $time (qw(5pm 10am 5:59pm 10:00pm 5:00 22:00 24:00)) {
    given($time) {
        when(/ ^ $hour12 $meridiem $ /x) { 
            my $hour = $+{hour};
            $hour += 12 if 'pm' eq lc $+{meridiem};
            tell_time($hour, "00") 
        }
        when(/ ^ $hour12 : $minute $meridiem $ /x) { 
            my $hour = $+{hour};
            $hour += 12 if 'pm' eq lc $+{meridiem};
            tell_time($hour, $+{minute}) 
        }
        when(/ ^ $hour24 : $minute $ /x) { 
            tell_time($+{hour}, $+{minute}) 
        }
        default {
            say "bad time: $time";
        }
    }
}

sub tell_time {
    my ($hour, $minute) = @_;
    say "it is $hour:$minute";
}
#/usr/bin/perl
使用5.010;
严格使用;
使用警告;
我的$hour24=qr/(?[1-9]| 1[0-9]| 2[0-3]);
我的$hour12=qr/(?[1-9]| 1[0-2])/;
我的$minute=qr/(?[0-5][0-9])/;
我的$meridiem=qr/(上午|上午|下午|下午)/;
我的美元时间(qw(下午5点10点5:59点10:00下午5:00 22:00 24:00)){
给定($时间){
当(/^$hour12$meridiem$/x){
我的$hour=$+{hour};
$hour+=12,如果'pm'eq lc$+{meridiem};
告诉你时间($hour,“00”)
}
当(/^$hour12:$minute$meridiem$/x){
我的$hour=$+{hour};
$hour+=12,如果'pm'eq lc$+{meridiem};
告诉你时间($hour,$+{minute})
}
当(/^$hour24:$minute$/x){
告诉你时间($+{hour},$+{minute})
}
违约{
说“坏时间:$time”;
}
}
}
分述时间{
我的($小时,$分钟)=@;
说“这是$hour:$minute”;
}

既然您使用的是5.10,那么最好在正则表达式中使用:

#!/usr/bin/perl

use 5.010;
use strict;
use warnings;

my $hour24   = qr/(?<hour>[1-9]|1[0-9]|2[0-3])/;
my $hour12   = qr/(?<hour>[1-9]|1[0-2])/;
my $minute   = qr/(?<minute>[0-5][0-9])/;
my $meridiem = qr/(?<meridiem>am|AM|pm|PM)/;

for my $time (qw(5pm 10am 5:59pm 10:00pm 5:00 22:00 24:00)) {
    given($time) {
        when(/ ^ $hour12 $meridiem $ /x) { 
            my $hour = $+{hour};
            $hour += 12 if 'pm' eq lc $+{meridiem};
            tell_time($hour, "00") 
        }
        when(/ ^ $hour12 : $minute $meridiem $ /x) { 
            my $hour = $+{hour};
            $hour += 12 if 'pm' eq lc $+{meridiem};
            tell_time($hour, $+{minute}) 
        }
        when(/ ^ $hour24 : $minute $ /x) { 
            tell_time($+{hour}, $+{minute}) 
        }
        default {
            say "bad time: $time";
        }
    }
}

sub tell_time {
    my ($hour, $minute) = @_;
    say "it is $hour:$minute";
}
#/usr/bin/perl
使用5.010;
严格使用;
使用警告;
我的$hour24=qr/(?[1-9]| 1[0-9]| 2[0-3]);
我的$hour12=qr/(?[1-9]| 1[0-2])/;
我的$minute=qr/(?[0-5][0-9])/;
我的$meridiem=qr/(上午|上午|下午|下午)/;
我的美元时间(qw(下午5点10点5:59点10:00下午5:00 22:00 24:00)){
给定($时间){
当(/^$hour12$meridiem$/x){
我的$hour=$+{hour};
$hour+=12,如果'pm'eq lc$+{meridiem};
告诉你时间($hour,“00”)
}
当(/^$hour12:$minute$meridiem$/x){
我的$hour=$+{hour};
$hour+=12,如果'pm'eq lc$+{meridiem};
告诉你时间($hour,$+{minute})
}
当(/^$hour24:$minute$/x){
告诉你时间($+{hour},$+{minute})
}
违约{
说“坏时间:$time”;
}
}
}
分述时间{
我的($小时,$分钟)=@;
说“这是$hour:$minute”;
}

我不确定给定/何时方面在这里是否重要。我只是将可能的模式组合在一个正则表达式中。结合特殊变量%+和定义的or运算符,我们可以使代码更加简洁

#!/usr/bin/perl

use strict;
use warnings;

my @times = qw( 12:59pm 12 1pm 13:11 11 11pm);

my $hour_pat   = '(?<hour>[0-9]{1,2})';
my $minute_pat = '(?<minute>[0-9]{2})';
my $ampm_pat   = '(?<ampm>am|pm)';

my $re = qr{
    \A
    (?:$hour_pat : $minute_pat $ampm_pat)
    |
    (?:$hour_pat : $minute_pat)
    |
    (?:$hour_pat $ampm_pat)
    |
    (?:$hour_pat)
    \z
}x;

for my $time ( @times ) {
    if ( $time =~ $re ) {
        tell_time( %+ );
    }
}

sub tell_time {
    my %time = @_;
    printf( "Hour: %2.2d, Minute: %2.2d, AMPM: %s\n",
        $time{hour},
        $time{minute} // 0,
        $time{ampm} // ( $time{hour} >= 12 ? 'pm' : 'am' ),
    );
    return;
}
#/usr/bin/perl
严格使用;
使用警告;
my@times=qw(12:59下午12:1下午13:11下午);
我的$hour_pat='(?[0-9]{1,2}');
我的$minute_pat='(?[0-9]{2}');
我的$ampm|pat='(?am|pm)';
我的$re=qr{
\A
(?:$hour_pat:$minute_pat$ampm_pat)
|
(?:$hour\u pat:$minute\u pat)
|
(?:$hour_pat$ampm_pat)
|
(?:$hour_pat)
\z
}x;
我的$time(@次){
如果($time=~$re){
告诉你时间(%+);
}
}
分述时间{
我的%time=@;
printf(“小时:%2.2d,分钟:%2.2d,振幅:%s\n”,
$time{hour},
$time{minute}//0,
$time{ampm}/($time{hour}>=12?'pm':'am'),
);
回来
}

我不确定给定/何时方面在这里是否重要。我只是将可能的模式组合在一个正则表达式中。结合特殊变量%+和定义的or运算符,我们可以