如何使用Perl的三元条件运算符构造复数形式的单词?

时间:2013-03-07 11:29:25

标签: perl if-statement nlp conditional-operator

我在编写涉及链式三元条件运算符的语句时遇到了一些麻烦。

显然我可以用标准方式编写它们,但知道它们为什么不能正常工作会很有用。

我想做的伪代码:

  

如果$ feature以's'结尾,则make $ group =大写$ feature

     

如果$ feature以'y'结尾,则删除y&在制作$ group =大写$ feature

之前用'ies'替换      

如果$ feature以其他任何内容结尾,请添加's'并使$ group =大写$ feature。

我尝试过使用c-style ifs:

substr($feature,-1) eq 'y' ? $group = uc(chop($feature)).'IES'
                           : substr($feature,-1) ne 's' ? $group = uc($feature).'S'
                                                        : $group = uc($feature);

substr($feature,-1) ne 's' ? substr($feature,-1) eq 'y' ? $group = uc(chop($feature)).'IES'
                                                        : $group = uc($feature).'S'
                           : $group = uc($feature);

如果我在$ feature中有一个以en结尾的字符串,则会找不到$group = uc($feature).'S'。我尝试使用eq 's'更改它,但随后它会在已经以S结尾的字符串上添加额外的s

任何帮助表示赞赏!

编辑:

这要归功于dan1111

$group = substr($feature,-1) ne 's' ? substr($feature,-1) eq 'y' ? uc(chop($feature)).'IES'
                                    : uc($feature).'S'
         : uc($feature);

2 个答案:

答案 0 :(得分:4)

Perl的一个怪癖是你可以实际分配给三元运算符:

condition ? $a : $b = 2;

这会将2分配给$a$b,具体取决于条件是否为真。

同样,在您的代码中uc($feature)被分配给条件的不同部分,具体取决于什么是真实的。

因此,如果您的代码中substr($feature,-1) ne 's'为真,则Perl会执行以下操作:

($group = uc($feature).'S') = uc($feature);

uc($feature)分配给$group

我认为Perl的这个功能很愚蠢,有点令人遗憾。尽管如此,您确实不应该使用三元运算符来控制流量。仅用于简单检查:

print $result == 1 ? 'yes' : 'no';

你当然不应该将多个三元运算符组合在一起,因为它非常混乱。这有什么问题?

if (substr($feature,-1) eq 'y')
{
    $group = uc(chop($feature)).'IES';
}
elsif (substr($feature,-1) ne 's')
{
    $group = uc($feature).'S';
}
else
{
    $group = uc($feature);
}

答案 1 :(得分:4)

以下是您当前问题的解决方案:

#!/usr/bin/env perl

use strict;
use warnings;

use feature 'say';

say make_group($_) for qw( curly status color );

=for specification

if $feature ends with 's', make $group = upper case $feature

if $feature ends with 'y', remove the y & replace with 'ies' before making $group = upper case $feature

if $feature ends with anything else, add an 's' and make $group = upper case $feature.

=cut

sub make_group {
    my ($feature) = @_;
    my $last = substr($feature, -1);

    my $group = $last eq 's' ? uc($feature)
              : $last eq 'y' ? do { chop($feature); uc("${feature}ies") }
              : uc("${feature}s")
    ;

    return $group;
}

__END__

但是,我会使用Lingua::EN::Inflect

#!/usr/bin/env perl

use strict;
use warnings;

use feature 'say';
use Lingua::EN::Inflect 'PL_N';

say uc(PL_N $_) for qw( curly status color );

__END__