Perl 使用正则表达式从文本字符串中提取浮点数



虽然看起来很简单 - 我没有一个使用正则表达式的perl代码的好例子,它从(任何)字符串中提取浮点,如下所示:

my $str = "process.pl: process workflow took 2.41153311729431 seconds.";
my $processTime = parseFloatFromString($str);
print "$processTimen";
and gives 2.41

我想提取一个不太精确的值 - 比如说小数点后 2 位。

谢谢。

有两个步骤:

  1. 从字符串中提取浮点数
  2. 将这些数字转换为所需的精度

第 1 步比您想象的要难,因此我建议使用现成的正则表达式(例如我从Regexp::Common年在这里使用的正则表达式)。

use Regexp::Common;
my @floats = $string =~ /($RE{num}{real})/g;

然后,您可以使用sprintf()printf()来更改精度。

printf "%0.2fn" for @floats;

您可以使用正则表达式提取数字并使用printf打印它,如下所示:

my ( $number ) = ( $str =~ /(d+(?:.d+)?)/ );
printf "%.2f", $number;

为清楚起见,上面的代码进行了简化。您还应该处理模式不匹配(无数字)的情况,例如:

$number = 0 unless defined $number;

根据需要调整正则表达式,除非您要处理浮点数的所有可能表示形式。

如果你真的想处理所有可能的输入,那么按照Dave Cross的建议使用库。但是由于"要求我们推荐或查找书籍、工具、软件库、教程或其他场外资源的问题对于 Stack Overflow 来说是题外话......">,我不会建议任何库。此外,看起来你只是在学习Perl,并愿意学习使用Perl正则表达式实际完成工作的方式。所以我建议你继续,阅读perlre,然后考虑你是否真的需要一个图书馆。

裸数字解析就是这个(?:d+(?:.d*)?|.d+)

要修改它以接受 0-2 位小数,它将是

https://regex101.com/r/n3gAFC/1

(?:d+(?:.d{0,2})?|.d{1,2})

扩大

(?:
d+ 
(?: . d{0,2} )?
|  . d{1,2} 
)

请注意,没有边界规范。
因此,必须对其进行修改才能在全球范围内使用。

通常,您可以在正则表达式后添加一个d*并包含一个捕获
组。
这将捕获您需要的内容,匹配您不需要的内容,从而
推进下一个数字的匹配位置。

(d+(?:.d{0,2})?|.d{1,2})d*

用法

如果您只想更改预先存在的浮点字符串,
则可以将正则表达式更改为需要小数点。
它与顶部的常规相同,删除其群集组上的选项
不会仅匹配数字。

(d+(?:.d*)|.d+)

如果你使用它,你可以在替代形式中利用sprint()。
这将一次完成所有操作,而无需提取、重新组装或以其他方式
丢弃现有字符串。

您有很多选项可供选择,这只是其中之一。

佩尔

use strict;
use warnings;
my $str = "process.pl: process 3 workflow took .0 days, 2.41153311729431 secs, 2411.53311729431 ms, 2411533.11729431 us.";
# To print without modify the string
print $str =~ s/(d+(?:.d*)|.d+)/sprintf("%0.2f",$1)/erg, "n";
# Or, print and modify the string at the same time
print $str = $str =~ s/(d+(?:.d*)|.d+)/sprintf("%0.2f",$1)/erg, "n";

输出

process.pl: process 3 workflow took 0.00 days, 2.41 secs, 2411.53 ms, 2411533.12 us.
process.pl: process 3 workflow took 0.00 days, 2.41 secs, 2411.53 ms, 2411533.12 us.
  1. 就像布罗丁指示 a/提取字段然后 b/正确呈现它一样。如果输出一致,我就拆分 它:
$procTime=split(' ',$str)[4]; # extract ... Thx to Sinan for improving this
printf "process time: %7.2fn", $procTime; # present
  1. 修复问题的根源!更改原始输出以生成 2 个小数 点。您不必做额外的工作来正确提取和呈现它

最新更新