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

时间:2017-06-15 15:53:01

标签: regex string perl

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

my $str = "process.pl: process workflow took 2.41153311729431 seconds.";
my $processTime = parseFloatFromString($str);
print "$processTime\n";

and gives 2.41

我想提取一个不太精确的值 - 例如2个小数点。

感谢。

4 个答案:

答案 0 :(得分:7)

这有两个步骤:

  1. 从字符串中提取浮点数
  2. 将这些数字转换为您所需的精确度
  3. 第1步比你想象的要难,所以我建议使用现成的正则表达式(就像我在Regexp::Common使用的那个)。

     {
       "rules":{
         "users":{
           "$uid": {
    
             ".write" : "$uid === auth.uid"
    
           }
         }
    
     } }
    

    然后,您可以使用use Regexp::Common; my @floats = $string =~ /($RE{num}{real})/g; sprintf()来更改精确度。

    printf()

答案 1 :(得分:1)

您可以使用正则表达式提取数字,然后使用printf进行打印,如下所示:

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

为清楚起见,上面的代码已经过简化。您还应该在模式不匹配(无数字)时处理这种情况,例如:

$number = 0 unless defined $number;

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

如果你真的想要处理所有可能的输入,那么就像Dave Cross建议的那样使用库。但是,因为“问题要求我们推荐或找到一本书,工具,软件库,教程或其他非现场资源是Stack Overflow的主题......”,我不会建议任何图书馆。此外,看起来你只是在学习Perl并且愿意学习使用Perl正则表达式实际完成的东西。所以我建议你继续阅读perlre,然后考虑一下你是否真的需要一个库。

答案 2 :(得分:0)

一个简单的数字解析就是这个(?:\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()
这将在不必提取,重新组装或以其他方式的情况下立即完成所有操作 垃圾现有的字符串。

你有很多选择可供选择,这只是一个。

Perl

 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.

答案 3 :(得分:-1)

  1. 像Brodin所说的那样/提取字段然后b /正确地呈现它。如果输出是一致的,我只是拆分 它:
  2. $procTime=split(' ',$str)[4]; # extract ... Thx to Sinan for improving this
    printf "process time: %7.2f\n", $procTime; # present
    
    1. 修复问题的根源!更改原始输出以生成2位小数 点。你不需要做额外的提取工作。正确呈现