2015-04-05 55 views
4

如何匹配浮点数(如1.234)或在处理字符串时使用“E符号”(如1.23e04)?如何在读取字符串时匹配浮点数

举个例子,让我们说,我想从一个数据文件类似下面的阅读数:

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.0
0.5 0.001218 

这的确是结果我想要实现,但是是否有更加优雅和通用的方式来处理这个问题?

注:数据文件可以有一个数字超过两列,可以有两种浮点表示和“E符号”。

+1

tonumber解析彩车本身:'在string.gmatch字(“0.0 1.295e-03 “,”[^%s] +“)打印(tonumber(word))end' – user2053898 2015-04-05 17:33:46

回答

3

假设每行只包含空格分隔的数字,可以让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 
+0

感谢您的回答。但是,通常情况下,数据文件中的第一行是由描述数字列的词组成的。我是否可以从第二行开始读取,以便仍然将数组索引从1开始,而不是从2开始(因为如果'split_number'读取了单词,它将返回'nil')? – 2015-04-05 17:58:26

+1

@PierPaolo似乎没问题。有多种方法可以跳过第一行,根据您的具体问题选择一种优雅的方式。 – 2015-04-05 18:05:47

1

这适用于对LUA REPL。

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

所以你的答案很简单,使用tonumber.

3

的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()