2015-04-05 57 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()