在 Perl 中用尾随零扩展字符串

Posted

技术标签:

【中文标题】在 Perl 中用尾随零扩展字符串【英文标题】:Expanding string with trailing zeros in Perl 【发布时间】:2013-08-05 13:59:24 【问题描述】:

我必须处理零件编号,什么是字母数字字符串。零件编号为 14 个字符长,但零件结构(s.c. 上层组件)编号较短。在元数据转换中,上层部件号需要扩展为 14 个字符的全长,尾随零。

我想出了以下解决方案

my $number = "M30SA0000002"; # same upper level part number
my $len = 14;

if (length($number) < $len) 
  print "Number [$number] is smaller, length (" . length ($number) . ")\n";
  $number = sprintf("%-$lens", $number);
  $number =~ tr/ /0/;

print "\New number [$number], length (" . length ($number) . ")\n"

这是输出

Number [M30SA0000002] is smaller, length (12)
New number [M30SA000000200], length (14)

虽然这会产生理想的结果,但在 2 行中执行这个简单的任务有点尴尬。有没有办法在一行中做到这一点?很遗憾sprintf 没有提供使用任何尾随字符扩展字符串的方法。

生产环境在 Windows Server 机器上运行,Perl 版本 5.14.2.1,没有 CPAN 模块,只有核心模块可用。

编辑: 我对 4 个解决方案进行了基准测试

use Benchmark qw(:all);
timethese(10000000, 
            'While' => sub  my $number = "M30SA0000002"; $number .= '0' while 14 > length $number; ,
            'Repeat' => sub  my $number = "M30SA0000002"; $number .= '0' x (14 - length $number); ,
            'Substring' => sub  my $number = "M30SA0000002"; $number = substr($number . "0" x 14, 0, 14); ,
            'Sprintf' => sub  my $number = "M30SA0000002"; $number = sprintf("%-14s", $number); $number =~ tr/ /0/; ,
);

结果如下:

Benchmark: timing 10000000 iterations of Repeat, Sprintf, Substring, While...
    Repeat:  2 wallclock secs ( 1.65 usr +  0.00 sys =  1.65 CPU) @ 6045949.21/s (n=10000000)
   Sprintf:  3 wallclock secs ( 3.90 usr +  0.00 sys =  3.90 CPU) @ 2564102.56/s (n=10000000)
 Substring:  3 wallclock secs ( 2.78 usr +  0.00 sys =  2.78 CPU) @ 3602305.48/s (n=10000000)
     While:  2 wallclock secs ( 2.81 usr +  0.00 sys =  2.81 CPU) @ 3561253.56/s (n=10000000)

重复解决方案似乎是所有解决方案中最快的。

【问题讨论】:

String::Formatter,当你想扩展 sprintf 并意识到你不能。 String::Formatter 不是核心 Perl 模块。我不能使用 CPAN 模块,或者至少我需要证明它的使用是合理的,但我必须经过很长的批准过程。所以我肯定会跳过这个。 是什么让 Web 上的随机代码(堆栈溢出)正常,但不能 (CPAN) 千倍测试,在其他地方有效使用? 我无法访问生产环境,也无法在那里安装任何东西。安装由其他部门完成。我无能为力。 我明白了,展开角度。您几乎总是可以模块复制代码来部署它。这比费力地重新发明***更实用。 【参考方案1】:

您可以将while 修饰符与“附加”赋值一起使用:

$number .= '0' while 14 > length $number;

或者做一些数学运算并使用重复运算符(感谢@loldop):

$number .= '0' x (14 - length $number);

【讨论】:

$number.='0'x(14 - length $number)? 我们的程序已经有很多循环了。您对提供的解决方案性能有何看法?【参考方案2】:

一步解决方案是添加大量0,并删除不需要的:

$number = substr($number . "0" x 14, 0, 14);

【讨论】:

以上是关于在 Perl 中用尾随零扩展字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何删除字符串中的前导零和尾随零? Python

JavaScript - 保持尾随零[重复]

从十进制字符串中删除尾随零

从Excel中删除尾随零并将小数点添加到字符串

将十进制字符串 IP 掩码转换为带有尾随零的无符号整数

截断尾随零 datagridview 列