【问题标题】:How to match a floating point number when reading a string读取字符串时如何匹配浮点数
【发布时间】:2015-04-05 17:13:32
【问题描述】:

在处理字符串时如何匹配1.234 之类的浮点数或使用1.23e04 之类的“E 表示法”的浮点数?

例如,假设我想从如下数据文件中读取数字:

0.0 1.295e-03
0.1 1.276e-03
0.2 1.261e-03
0.3 1.247e-03
0.4 1.232e-03
0.5 1.218e-03

目前我编写了自己的函数来将每一行转换为它所包含的数字,但它不是很优雅且根本不便携:具有不同“布局”的数据文件会出错。

这是一个简单的例子,它读取已经呈现的数据文件并打印以筛选数字:

function read_line(str)
   local a, b, c, d, e = str:match(
      "^%s*(%d+)%.(%d+)%s+(%d+)%.(%d+)[Ee]%-*(%d+)")
   if str:match("%-") then
      e = -tonumber(e)
   end
   local v1 = a + .1*b
   local v2 = (c + .001*d) * 10^e
   return v1, v2
end

for line in io.lines("data.txt") do
   print(read_line(line))
end

结果如下:

0   0.001295
0.1 0.001276
0.2 0.001261
0.3 0.001247
0.4 0.001232
0.5 0.001218

这确实是我想要达到的结果,但是有没有更优雅通用的方法来处理这个问题?

注意:数据文件可以有两列以上的数字,并且可以有浮点表示和“E 表示法”。

【问题讨论】:

  • tonumber 解析浮点数:for word in string.gmatch("0.0 1.295e-03", "[^%s]+") do print(tonumber(word)) end

标签: string lua lua-patterns


【解决方案1】:

假设每一行只包含空格分隔的数字,您可以让tonumber 完成繁重的工作,而不是手动匹配数字:

function split_number(str)
    local t = {}
    for n in str:gmatch("%S+") do
        table.insert(t, tonumber(n))
    end
    return table.unpack(t)
end

for line in io.lines("data.txt") do
    print(split_number(line))
end

【讨论】:

  • 感谢您的回答。然而,通常,数据文件的第一行由描述数字列的单词组成。我可以从第二行开始读取,以便仍然从 1 而不是从 2 索引数组(因为如果 split_number 读取它返回 nil 的单词)?
  • @PierPaolo 似乎还可以。跳过第一行的方法不止一种,根据你的具体问题选择一种优雅的方式。
【解决方案2】:

Lua 可以直接读取数字:

f=assert(io.open("data.txt"))
while true do
    local a,b=f:read("*n","*n")
    if b==nil then break end
    print(a,b)
end
f:close()

【讨论】:

    【解决方案3】:

    这适用于 lua REPL。

    a = tonumber('4534.432')
    b = tonumber('4534.432')
    a==b 
    

    所以你的答案就是使用tonumber.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-18
      • 1970-01-01
      • 2014-09-30
      相关资源
      最近更新 更多