首页 > 解决方案 > 如何使用文本中的正则表达式选择浮点或整数

问题描述

我想从某些文本中匹配给定的整数或浮点数,但仅限于特定的行,因为相似的数字可以出现在不同的位置。

这就是我的输入,数字是组成的,不要试图将“总”与“部分”相关联:

===> Verifying dependencies...
===> Compiling sample
===> Performing cover analysis...
  |------------------------|------------|
  |                module  |  coverage  |
  |------------------------|------------|
  |            sample_app  |    12.94%  |
  |            sample_sup  |    56.78%  |
  |                sample  |       96%  |
  |------------------------|------------|
  |                 total  |    23.02%  |
  |------------------------|------------|
  coverage calculated from:
    /tmp/workspace/_build/test/cover/ct.coverdata
    /tmp/workspace/_build/test/cover/eunit.coverdata
  cover summary written to: /tmp/workspace/_build/test/cover/index.html

我只想提取.行中的数字 。这是我到目前为止的正则表达式:23.02total

^.+total.+(\d+|\d+\.\d+)%.+$

但它不能很好地工作,它只匹配该行的最后一个数字。

我正在测试Rubular上的模式。

标签: regexruby

解决方案


你有两个问题。第一个.+是贪婪的,这意味着,如果用于从文件中搜索单行,它将吞噬尽可能多的字符(换行符除外),但仍然确保匹配,这意味着匹配最后一个数字。

第二个问题是,如果将文件读入字符串并搜索该字符串,.*将不会超过第一行,因为它不会匹配换行符。这可以通过添加一个多行修饰符 ( /m) 来轻松解决,该修饰符指示.*匹配所有字符,包括换行符。

如果您将文件读入字符串,您可以使用以下正则表达式从字符串中提取感兴趣的字符。

r = /
    ^          # match beginning of line
    [ ]*       # match 0+ spaces
    \|         # match a toothpick
    [ ]+       # match 1+ spaces
    total      # match 'total'   
    [ ]+       # match 1+ spaces
    \|         # match a toothpick
    [ ]+       # match 1+ spaces
    \K         # forget everything matched so far
    \d+        # match a digit
    (?:\.\d+)  # match '.' then 1+ digits in non-capture group
    ?          # optionally match the non-capture group
    (?=        # begin a positive lookahead
      %        # match '%'
      [ ]+     # match '%' then 1+ spaces
      \|[ ]*   # match a toothpick then 0+ spaces
      $        # match end-of-line
    )          # end positive lookahead
    /x         # free-spacing mode

我已经以自由间距模式1编写了正则表达式,以使其自我记录。它通常写成如下。

/^ *\| +total +\| +\K\d+(?:\.\d+)?(?=% +\| *$)/

假设您将文件读入由变量保存的字符串str

str =<<~END
===> Verifying dependencies...
===> Compiling sample
===> Performing cover analysis...
  |------------------------|------------|
  |                module  |  coverage  |
  |------------------------|------------|
  |            sample_app  |    12.94%  |
  |            sample_sup  |    56.78%  |
  |                sample  |       96%  |
  |------------------------|------------|
  |                 total  |    23.02%  |
  |------------------------|------------|
  coverage calculated from:
    /tmp/workspace/_build/test/cover/ct.coverdata
    /tmp/workspace/_build/test/cover/eunit.coverdata
  cover summary written to: /tmp/workspace/_build/test/cover/index.html
END

然后

str[r] #=> "23.02" 

1 在自由间距模式下,所有空格都会在正则表达式被解析之前被去除,这就是为什么必须保护正则表达式中的空格。我已经通过将每个空格放在字符类中来做到这一点,但是它们可以被转义或\s可以被使用(如果合适的话)。


推荐阅读