最近有空空閑 整理點東西吧
相信這個在遊戲腳本裡有那麼一點點用處
1.先來個簡單的
-------------------------------------------------
--功能:字元串按格式的分解
--輸入:字元串,格式符号
--輸出:分割好的字元串table
function trimstr(str, c)
local t={}
if nil~=str then
local s=string.gsub(str, "^%s*(.-)%s*$", "%1") --去除字元串首尾的空格
if nil==string.find(c, " ") then --分隔符不為空格
local strtmp=string.gsub(s, " ", "") --消除所有空格
local strall=string.gsub(strtmp, c, " ") --用空格代替分隔符
s=strall
end
for k, v in string.gmatch(s, "%S*") do
if 0~=string.len(k) then --擷取長度非0的字元串
t[#t+1]=k
end
end
end
return t
end
--功能:解析非字段名
--輸入: 字段名table,讀取的一行字元串
--輸出: 解析後的字元串
function parseline(tfieldname, rline)
local t={} --存儲每一行的分割後的資料
local strinfo="" --存放解析後的字元串
local num=0 --預設的每一行字段個數
t=trimstr(rline, " ") --以空格為分隔符擷取
num=#(tfieldname)>#(t) and #(t) or #(tfieldname)--取字段名和資料名較少的
for i=1, num do
local strinfotmp=string.format("%s=\"%s\",", tfieldname[i], t[i])
strinfo=string.format("%s%s", strinfo, strinfotmp)
end
return strinfo
end
-----------------------------------------------------------
function txttolua(txtname, luaname)
local name=luaname and luaname or txtname --第二個參數若為空則和第一個一樣
local readfile = io.open(txtname..".txt","r") --讀取檔案
assert(readfile)
local writefile = io.open(name..".lua","w") --寫入檔案以.lua結尾(w覆寫)
assert(writefile)
local tfieldname={} --檔案中字段名的集合
for strfield in readfile:lines() do --一行一行讀取字段名
local tmp=string.gsub(strfield, "^%s*(.-)%s*$", "%1") --去除首尾空格
if 0~=string.len(tmp) then --不是空行
if 1~=select(1, string.find(tmp, "#")) then --以#号開頭的為注釋
tfieldname=trimstr(tmp, " ") --以空格為分隔符擷取
break
end
end
end
local i=1
writefile:write("tb={\n") --寫入内容
for rowline in readfile:lines() do --一行一行讀取非字段名
local tmp=string.gsub(rowline, "^%s*(.-)%s*$", "%1") --去除首尾空格
if 1~=select(1, string.find(tmp, "#")) then --以#号開頭的為注釋
local strinfo=parseline(tfieldname, rowline) --解析每一行資料
local writeinfo=string.format("\t[%d]={%s},\n", i, strinfo)
writefile:write(writeinfo) --寫入内容
i=i+1
end
end
writefile:write("\t}") --寫入内容
readfile:close() ---調用結束後記得關閉
writefile:close() --調用結束後記得關閉
end
-----------------------------------------------------------
txttolua("task", "task")
寫的txt檔案:

運作後生成的lua檔案:
2.再來個按條件擷取的
-------------------------------------------------
--功能:解析數學符号
--輸入:table形式的條件each(如 2-10 >0),要比較的數(如 5)
--輸出:滿足條件則為ture 不滿足則為false
function parsemathsign(each, num)
if nil~=string.find(num, "%D") or nil==each then --傳入的有非數字(資料中)
return false
end
for i=1, #(each) do
local n=string.sub(each[i], 2, -1) --擷取數字(條件中)
if nil==string.find(n, "%D") then --沒有找到非數字的
if nil~=string.find(each[i], ">") then --大于
if num-n>0 then --滿足
return true
end
end
if nil~=string.find(each[i], "<") then --小于
if num-n<0 then --滿足
return true
end
end
end
if nil~=string.find(each[i], "-") then --從...到...
local fromto={}
fromto=trimstr(each[i], "-") --存了min和max
if nil==string.find(fromto[1], "%D") and
nil==string.find(fromto[2], "%D") then --沒有找到非數字元号則執行
if num-fromto[1]>=0 and num-fromto[2]<=0 then--滿足
return true
end
end
end
end
return false
end
-------------------------------------------------
--功能:解析字元串
--輸入:table形式的條件each,要比較的字元串
--輸出:滿足條件則為ture 不滿足則為false
function parsestring(each, str)
for i=1, #(each) do
--以星号開頭的字元串
if 1==select(1, string.find(each[i], "*")) then
local strtmp=string.gsub(each[i], "*", "") --消除星号
local b, e=string.find(str, strtmp)
if string.len(str)==e and string.len(strtmp)==e-b+1 then
return true
end
--以星号結尾的字元串
elseif string.len(each[i])==select(1, string.find(each[i], "*")) then
local strtmp=string.gsub(each[i], "*", "") --消除星号
local b, e=string.find(str, strtmp)
if 1==b and string.len(strtmp)==e then
return true
end
--星号在字元串的中間
elseif nil~=string.find(each[i], "*") then --第*章節
local t={}
t=trimstr(each[i], "*")
local b1, e1=string.find(str, t[1])
local b2, e2=string.find(str, t[2])
if string.len(str)==e2 and string.len(t[2])==e2-b2+1 and
1==b1 and string.len(t[1])==e1 then
return true
end
--無星号完全比對
else
if each[i]==str then --滿足
return true
end
end
end
return false
end
-------------------------------------------------
--功能:解析非字段名
--輸入: 字段名table,字段名條件table,讀取的一行字元串
--輸出: 解析後的字元串(正确部分+錯誤部分)
function parseline(tfieldname, tcondition, rline)
local t={} --存儲每一行的分割後的資料
local strinfo="" --存放解析後的字元串
local strerr="" --存放錯誤資訊
local ierror=-1 --0表示正常 -1表示錯誤
local num=0 --預設的每一行字段個數
t=trimstr(rline, " ") --以空格為分隔符擷取
num=#(tfieldname)>#(t) and #(t) or #(tfieldname) --取字段名和資料名較少的
for i=1, num do
--該字段中有條件
if nil~=tcondition[i] then
ierror=-1 --每一行之前都假設為錯誤
local each={} --存儲每個字段名後的條件
each=trimstr(tcondition[i], ",")--以,為分隔符擷取
--指定大小關系
if nil~=string.find(tcondition[i], "<") or
nil~=string.find(tcondition[i], ">") or
nil~=string.find(tcondition[i], "-") then
if true==parsemathsign(each, t[i]) then --進行數學符号的解析并判斷是否滿足條件
ierror=0
end
--指定字元串
else
if true==parsestring(each, t[i]) then --進行字元串的解析并判斷是否滿足條件
ierror=0
end
end
--判斷是否滿足指定條件
if 0==ierror then --滿足則寫入strinfo
local strinfotmp=string.format("%s=\"%s\",", tfieldname[i], t[i])
strinfo=string.format("%s%s", strinfo, strinfotmp)
elseif -1==ierror then --不滿足則寫入strerr
local strerrtmp=string.format("%s=\"%s\",", tfieldname[i], t[i])
strerr=string.format("%s%s", strerr, strerrtmp)
end
--字段中沒有指定條件
else
if 0==string.len(strerr) then
local strinfotmp=string.format("%s=\"%s\",", tfieldname[i], t[i])
strinfo=string.format("%s%s", strinfo, strinfotmp)
end
end--if
end --for
--擷取不滿足指定條件的整行資料
if 0~=string.len(strerr) then
local str=strerr
strinfo=""
strerr=""
for i=1, num do
local strerrtmp=string.format("%s=\"%s\",", tfieldname[i], t[i])
strerr=string.format("%s%s", strerr, strerrtmp)
end
strerr=string.format("<%s> ERROR:<%s>", strerr, str)
end
--print("yes:"..strinfo, "\nerror:"..strerr)
return strinfo, strerr
end
解析條件:
function parsecondition(txtname)
local readfile = io.open(txtname..".txt","r") --讀取檔案
assert(readfile)
local i=1
local t={} --條件檔案中的條件集合
for str in readfile:lines() do --一行一行讀取字段名
local tmp=string.gsub(str, "^%s*(.-)%s*$", "%1")--去除首尾空格
if 1~=select(1, string.find(tmp, "#")) then --以#号開頭的為注釋
t[i]=m.trimstr(tmp, ":") --以:為分隔符擷取
i=i+1
end
end
readfile:close()
return t
end
-------------------------------------------------
--功能:從txt檔案轉換到lua檔案
--輸入:條件table txt檔案名 lua檔案名(若無則與txt檔案名一樣)
--輸出:生成lua檔案和log.log檔案
function txttolua(t, txtname, luaname)
local name=luaname and luaname or txtname --第三個參數若為空則和第二個一樣
local logfile=io.open("log.log", "a") --操作log(a追加)
assert(logfile)
local readfile = io.open(txtname..".txt","r") --讀取檔案
assert(readfile)
local writefile = io.open(name..".lua","w") --寫入檔案以.lua結尾(w覆寫)
assert(writefile)
logfile:write("----------------------------\n") --寫入log中
logfile:write("操作時間: "..os.date().."\n") --寫入log中
local tfieldname={} --檔案中字段名的集合
for strfield in readfile:lines() do --一行一行讀取字段名
local tmp=string.gsub(strfield, "^%s*(.-)%s*$", "%1") --去除首尾空格
if 1~=select(1, string.find(tmp, "#")) then --以#号開頭的為注釋
tfieldname=trimstr(tmp, " ") --以空格為分隔符擷取
break
end
end
local tcondition={}
for i=1, #(t) do
for k, v in pairs(t[i]) do
for j=0, #(tfieldname) do
if v==tfieldname[j] then
tcondition[j]=t[i][2]
end
end
end
end
local i=1
writefile:write("tb={\n") --寫入内容
for rowline in readfile:lines() do --一行一行讀取非字段名
local tmp=string.gsub(rowline, "^%s*(.-)%s*$", "%1")--去除首尾空格
if 1~=select(1, string.find(tmp, "#")) then --以#号開頭的為注釋
local strinfo, strerror=parseline(tfieldname, tcondition, rowline) --解析每一行資料
if 0~=string.len(strerror) then
local writeinfo=string.format("檔案<%s.txt>: %s\n", txtname, strerror)
logfile:write(writeinfo) --寫入log中
elseif 0~=string.len(strinfo) then
local writeinfo=string.format("\t[%d]={%s},\n", i, strinfo)
writefile:write(writeinfo) --寫入内容
i=i+1
end
end
end
writefile:write("\t}") --寫入内容
logfile:close()
writefile:close()
end
-----------------------------------
--條件與條件直接用逗号分開
-- * 表示比對(隻能用一個*)
-- str 表示完全比對
-- > 如:>9
-- < 如:<100
-- - 如:5-100 (包括5和100) 不支援負号
--
-- txttolua函數
-- 輸入: 條件table, txt檔案名, lua檔案名(若無則與txt檔案名一樣)
-- 輸出:生成lua檔案和log.log檔案
---------------------------------------
local t={}
t=c.parsecondition("task_condition")
m.txttolua(t, "task")
資料:
條件:
出錯日記:
寫入到lua檔案中的東西