天天看點

lua檔案操作(3)----txt檔案轉換成lua檔案的table格式

最近有空空閑  整理點東西吧

相信這個在遊戲腳本裡有那麼一點點用處

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檔案操作(3)----txt檔案轉換成lua檔案的table格式

運作後生成的lua檔案:

lua檔案操作(3)----txt檔案轉換成lua檔案的table格式

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檔案操作(3)----txt檔案轉換成lua檔案的table格式

條件:

lua檔案操作(3)----txt檔案轉換成lua檔案的table格式

出錯日記:

lua檔案操作(3)----txt檔案轉換成lua檔案的table格式

寫入到lua檔案中的東西

lua檔案操作(3)----txt檔案轉換成lua檔案的table格式