如何在Perl中检索整数的序数后缀(如st,nd,rd,th)

时间:2012-07-06 21:31:11

标签: regex perl perl-module perl-data-structures

我有号码,需要添加后缀:'st','nd','rd','th'。例如:如果数字为42,则后缀为'nd',521为'st',113为'th',依此类推。 我需要在perl中执行此操作。任何指针。

5 个答案:

答案 0 :(得分:27)

使用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;
  }
  ...
}

答案 1 :(得分:16)

试试这个:

my $ordinal;
if ($foo =~ /(?<!1)1$/) {
    $ordinal = 'st';
} elsif ($foo =~ /(?<!1)2$/) {
    $ordinal = 'nd';
} elsif ($foo =~ /(?<!1)3$/) {
    $ordinal = 'rd';
} else {
    $ordinal = 'th';
}

答案 2 :(得分:7)

试试这个简短的子程序

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

答案 3 :(得分:3)

这是一个解决方案which I originally wrote for a code golf challenge,稍作重写,以符合非高尔夫代码的常规最佳做法:

$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映射到{ {1}}和undef的任何其他值。最后,rd运算符将undef替换为||

如果您不喜欢th,基本上可以编写相同的解决方案,例如像这样:

s///e

或作为一种功能:

for ($number) {
    /(1?\d)$/ or next;
    $_ .= (qw'th st nd rd')[$1] || 'th';
}

答案 4 :(得分:1)

另一个解决方案(虽然我喜欢预先存在的答案,这些答案独立于更好地使用模块):

use Date::Calc 'English_Ordinal';
print English_Ordinal $ARGV[0];