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文件:

 

 

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文件中的东西

 

 

你可能感兴趣的:(Lua)