我有一个数字,需要添加后缀:'st'、'nd'、'rd'、'th'。例如:如果数字是42,后缀为'nd',521是'st',113是'th'等等。 我需要在perl中完成这个操作。有什么指导吗。
我有一个数字,需要添加后缀:'st'、'nd'、'rd'、'th'。例如:如果数字是42,后缀为'nd',521是'st',113是'th'等等。 我需要在perl中完成这个操作。有什么指导吗。
使用Lingua::EN::Numbers::Ordinate。从概要看:
use Lingua::EN::Numbers::Ordinate;
print ordinate(4), "\n";
# prints 4th
print ordinate(-342), "\n";
# prints -342nd
# Example of actual use:
...
for(my $i = 0; $i < @records; $i++) {
unless(is_valid($record[$i]) {
warn "The ", ordinate($i), " record is invalid!\n";
next;
}
...
}
试试这个:
my $ordinal;
if ($foo =~ /(?<!1)1$/) {
$ordinal = 'st';
} elsif ($foo =~ /(?<!1)2$/) {
$ordinal = 'nd';
} elsif ($foo =~ /(?<!1)3$/) {
$ordinal = 'rd';
} else {
$ordinal = 'th';
}
尝试这个简短的子程序
use strict;
use warnings;
sub ordinal {
return $_.(qw/th st nd rd/)[/(?<!1)([123])$/ ? $1 : 0] for int shift;
}
for (42, 521, 113) {
print ordinal($_), "\n";
}
输出
42nd
521st
113th
for
循环?也可以使用 return int(shift) . (qw/...
。对于多个参数,由于 return
语句的存在,for
循环也无法正常工作。虽然现在它能够正常运行,但是我是否错过了循环的某些内容? - Birei$_[0]
放入$_
的一种方式。你的方式行不通,因为正则表达式需要值在$_
中。这非常类似于新的given
语言单词,但你不能像使用for
那样将其用作语句修饰符。 - Borodin$_
的意思。这值得一个 +1。 - Bireifor
就是所有破损的given
应该做的,但这是另一回事。 - Borodin$number =~ s/(1?\d)$/$1 . ((qw'th st nd rd')[$1] || 'th')/e;
(1?\d)$
匹配数字的最后一位,如果前面的数字是1
,则还会匹配它前面的数字。接下来,替换操作使用匹配到的数字作为列表(qw'th st nd rd')
的索引,将0映射为th
,将1映射为st
,将2映射为nd
,将3映射为rd
,其他任何值都映射为undef。最后,||
运算符将undef替换为th
。s///e
,基本上可以像这样编写相同的解决方案:for ($number) {
/(1?\d)$/ or next;
$_ .= (qw'th st nd rd')[$1] || 'th';
}
sub ordinal ($) {
$_[0] =~ /(1?\d)$/ or return;
return $_[0] . ((qw'th st nd rd')[$1] || 'th');
}
use Date::Calc 'English_Ordinal';
print English_Ordinal $ARGV[0];
这里有一个完全不复杂的方法来实现。
sub english_ordinal( $n ) {
my @suffixes = qw( th st nd rd th th th th th th );
my $x = $n % 100;
my $suffix;
if ( $x >= 10 && $x <= 19 ) {
$suffix = 'th';
}
else {
$suffix = $suffixes[$x % 10];
}
return "$n$suffix";
}
你是否希望让它占用更少的空间,更聪明,也许速度更快?当然,但其他答案已经涵盖了这些问题。
顺便加上一些单元测试。
my %tests = (
0 => '0th',
1 => '1st',
2 => '2nd',
3 => '3rd',
4 => '4th',
5 => '5th',
6 => '6th',
7 => '7th',
8 => '8th',
9 => '9th',
10 => '10th',
11 => '11th',
12 => '12th',
13 => '13th',
14 => '14th',
15 => '15th',
16 => '16th',
17 => '17th',
18 => '18th',
19 => '19th',
20 => '20th',
21 => '21st',
22 => '22nd',
23 => '23rd',
24 => '24th',
25 => '25th',
26 => '26th',
27 => '27th',
28 => '28th',
29 => '29th',
30 => '30th',
100 => '100th',
101 => '101st',
102 => '102nd',
111 => '111th',
);
while ( my ($n,$s) = each %tests ) {
is( english_ordinal($n), $s, "$n -> $s" );
}
sub ordinal { my $n = shift; return "${n}st" if $n =~ /(?(注意:这个函数也会返回数字本身)
- matemaciek