模块:Lang zh cn/Parser

来自Noita Wiki
跳转到导航 跳转到搜索

可在模块:Lang zh cn/Parser/doc创建此模块的帮助文档

---解析器
local p = {}--返回的变量

---@param str string
function p.parseCSV(str)
    local cellDatas = {}
    local rowHeads = {}
    local result;
    local tempKeyCount = 1
    result = {
        rowHeads = rowHeads,
        tempKey = nil,
        ---设置指定行列单元格的值
        ---* 使用行列号(从1开始的数字)来作为索引
        ---* 不存在的单元格会自动新建
        ---@param row number
        ---@param column number
        set = function(row, column, value)
        	if column == 1 then 
        		tempKeyCount = 1
        		cellDatas[value] = {}
        		tempKey = value
        	end
        	cellDatas[tempKey][tempKeyCount] = value
			tempKeyCount = tempKeyCount + 1
            if row == 1 then rowHeads[value] = column end
        end,
    }
    local state_quotationMark = false   -- 双引号状态机
    local usub = string.sub
    local codepoint = string.byte
    local StartPos = 1 --用于记录一个需要被剪切的字符串的起始位
    local charNum = 0
    local posRow= 1
    local posColumn = 1
    for i=1, #str do
        charNum = codepoint(str,i,i)
        if state_quotationMark then -- 处于双引号包裹中
        	state_quotationMark = (charNum ~= 34)--减少分支优化
        --[[目前Noita CSV不包括转义符转引号,所以这部分代码暂时不需要
        	if charNum == 92 then --转义符考虑
        		i = i + 1 --当前字符是转义符,下一个字符也应该跳过,所以加1,下一次循环再加1
        	end]]
        else
            if charNum == 34 then -- 34为"符号
                state_quotationMark = true -- 进入双引号包裹
            elseif charNum == 44 then     -- 分隔符为en逗号 44为,
                result.set(posRow, posColumn, usub(str,StartPos,i-1))--i-1是为了不要把,加进去
                StartPos = i + 1--重设起始位
                posColumn = posColumn + 1
            elseif charNum == 10 then --10为\n
                -- 对连续换行(空行)和"\n"(Windows换行符)特殊处理
                if (codepoint(str, i - 1, i - 1) ~= 10) then
                    result.set(posRow, posColumn, usub(str,StartPos,i-1))
                    StartPos = i + 1
                    posRow = posRow + 1
                    posColumn = 1
                end
            end
        end
    end
    result.set(posRow, posColumn, usub(str,StartPos,#str-1))
    return {rowHeads = result.rowHeads,cellDatas = cellDatas}
end

return p