Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.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
Regex 如何检索整数';Perl中的顺序后缀(如st、nd、rd、th)_Regex_Perl_Perl Module_Perl Data Structures - Fatal编程技术网

Regex 如何检索整数';Perl中的顺序后缀(如st、nd、rd、th)

Regex 如何检索整数';Perl中的顺序后缀(如st、nd、rd、th),regex,perl,perl-module,perl-data-structures,Regex,Perl,Perl Module,Perl Data Structures,我有号码,需要加后缀:“st”、“nd”、“rd”、“th”。例如:如果数字是42,后缀是'nd',521是'st',113是'th',依此类推。 我需要用perl来做这件事。任何指针。尝试以下操作: my $ordinal; if ($foo =~ /(?<!1)1$/) { $ordinal = 'st'; } elsif ($foo =~ /(?<!1)2$/) { $ordinal = 'nd'; } elsif ($foo =~ /(?<!1)3$/)

我有号码,需要加后缀:“st”、“nd”、“rd”、“th”。例如:如果数字是42,后缀是'nd',521是'st',113是'th',依此类推。 我需要用perl来做这件事。任何指针。

尝试以下操作:

my $ordinal;
if ($foo =~ /(?<!1)1$/) {
    $ordinal = 'st';
} elsif ($foo =~ /(?<!1)2$/) {
    $ordinal = 'nd';
} elsif ($foo =~ /(?<!1)3$/) {
    $ordinal = 'rd';
} else {
    $ordinal = 'th';
}
my$ordinal;
如果($foo=~/(?使用概要中的:

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;
  }
  ...
}
使用语言::EN::数字::纵坐标;
打印坐标(4),“\n”;
#印刷品第四
打印坐标(-342),“\n”;
#印刷品-342
#实际使用示例:
...
对于(我的$i=0;$i<@records;$i++){
除非(u有效($record[$i]){
警告“坐标($i),“记录无效!\n”;
下一个
}
...
}

试试这个简短的子程序

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";
}
以下是一个解决方案,稍加修改以符合非高尔夫代码的常规最佳实践:

$number =~ s/(1?\d)$/$1 . ((qw'th st nd rd')[$1] || 'th')/e;
它的工作方式是,regexp
(1?\d)$
匹配数字的最后一位,如果是
1
,则加上前一位。然后替换使用匹配的数字作为列表的索引
,将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');
}
另一个解决方案(尽管我更喜欢与使用模块无关的现有答案):


对难以捉摸的零宽度负片后看断言的生产性使用进行向上投票正如Bill Ruppert所指出的,已经有了一个CPAN模块。尽管有一个CPAN解决方案,我也喜欢这个。它经过深思熟虑,可读性强,没有依赖性,并且与任何整数的CPAN解决方案一样精确。同样,但重写得更精细:
sub-ordinal{my$n=shift;如果$n=~/(?。(注意:这也返回数字本身)这里有一点我不完全理解。当只有一个元素作为参数时,为什么要使用
for
循环?它也可以工作
返回int(shift)。(qw/…
。对于几个参数,
循环也不会工作,因为
返回
语句。它可以正常工作,但我是否错过了循环的某些内容?@Birei:这只是一种放置
$[0]的方式
转换为
$\
。你的方式不起作用,因为正则表达式需要值位于
$\
中。它非常像新的
给定的
语言单词,但你不能像
转换为
那样使用它作为语句修饰符。啊,好的。谢谢。没有理解
$\
的意思。它应该得到+1。@BillRuppert:t汉克斯·比尔。我忘了这是我写的!我认为
for
是所有被破坏的
应该做的事,但那是另一回事了
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];