如何编写正则表达式以匹配带或不带前导零的数字并用特定文本排除数字?

时间:2014-04-02 16:20:04

标签: ruby regex regex-lookarounds

我正在尝试从文件名中提取测量值,它们非常不一致;例如:

  • FSTCAR.5_13UNC_1.00
  • FSTCAR.5_13UNC_1.00GR5P
  • FSTCAR.5_13UNC_1.00SS316

我必须能够匹配所有数字(带小数和不带前导零)。我想我有这个工作:

/\d*\.?\d+/i

但是,我还希望能够排除SS或GR之前的数字。这样的事似乎是部分工作:

/(?<!GR|SS)\d*\.?\d+/i

这将从上面的FSTCAR.5_13UNC_1.00GR5P中排除5,但不排除任何超过一位的数字,因此316中的16将是匹配。我在红宝石中这样做。

2 个答案:

答案 0 :(得分:0)

要修复SS和GR排除,请尝试以下操作:

/(?<!GR|SS)[\d\.]+/i

我不确定你的布局究竟是什么,但使用它会更快地让你的负面看法背后:

(?<![GRS]{2})

编辑:+仍然不够贪婪。

您可能需要使用两个正则表达式。一个用于删除GR / SS编号,一个用于匹配(注意:我对Ruby不太熟悉):

val.gsub('/[GRS]{2}[\d\.]+/', '')
val =~ /[\d\.]+/

答案 1 :(得分:0)

任何时候你必须抖动浮点数字符串,这不是一个微不足道的壮举 这只需要你的最后一个正则表达式,并为lookbehind添加一些额外的东西 这确保引擎不会绕过一个数字以匹配正则表达式。

 #  (?<!GR)(?<!SS)(?<![.\d])\d*\.?\d+

 # (?<! GR | SS | [.\d] )
 (?<! GR )
 (?<! SS )
 (?<! [.\d] )
 \d* \.? \d+ 

Perl测试用例

 @ary = (
   'FSTCAR.5_13UNC_1.00 ',
   'FSTCAR.5_13UNC_1.00GR5P',
   'FSTCAR.5_13UNC_1.00SS316'
 );

 foreach $fname (@ary)
 {
    print "filename:  $fname\n";
    while ( $fname =~ /(?<!GR)(?<!SS)(?<![.\d])\d*\.?\d+/ig ) {

       print " found $&\n";
    }
 }

输出&gt;&gt;

 filename:  FSTCAR.5_13UNC_1.00
  found .5
  found 13
  found 1.00
 filename:  FSTCAR.5_13UNC_1.00GR5P
  found .5
  found 13
  found 1.00
 filename:  FSTCAR.5_13UNC_1.00SS316
  found .5
  found 13
  found 1.00