-- Hàm chuyển chuỗi thành table function stringToTable(str) -- Loại bỏ khoảng trắng thừa ở đầu và cuối str = str:match("^%s*(.-)%s*$") -- Kiểm tra nếu chuỗi rỗng hoặc không phải table if str == "" or str:sub(1, 1) ~= "{" or str:sub(-1) ~= "}" then return nil, "Invalid table string" end -- Hàm phụ để phân tích chuỗi thành table local function parse(str, pos) local t = {} pos = pos or 1 local len = #str while pos <= len do -- Bỏ qua khoảng trắng while pos <= len and str:sub(pos, pos):match("%s") do pos = pos + 1 end -- Kết thúc table if pos > len then break end if str:sub(pos, pos) == "}" then return t, pos + 1 end -- Phân tích key local key if str:sub(pos, pos) == "[" then -- Key dạng [key] pos = pos + 1 local start = pos local bracket_count = 1 while pos <= len and bracket_count > 0 do if str:sub(pos, pos) == "[" then bracket_count = bracket_count + 1 elseif str:sub(pos, pos) == "]" then bracket_count = bracket_count - 1 end pos = pos + 1 end if bracket_count ~= 0 then return nil, "Invalid key syntax" end local key_str = str:sub(start, pos - 2) key = load("return " .. key_str)() if key == nil then return nil, "Invalid key" end -- Bỏ qua dấu "=" while pos <= len and str:sub(pos, pos):match("%s") do pos = pos + 1 end if str:sub(pos, pos) ~= "=" then return nil, "Expected '=' after key" end pos = pos + 1 else -- Key dạng identifier hoặc số thứ tự local start = pos while pos <= len and str:sub(pos, pos):match("[%w_]") do pos = pos + 1 end key = str:sub(start, pos - 1) if key == "" then key = #t + 1 else -- Bỏ qua dấu "=" while pos <= len and str:sub(pos, pos):match("%s") do pos = pos + 1 end if str:sub(pos, pos) ~= "=" then pos = start key = #t + 1 else pos = pos + 1 end end end -- Phân tích value while pos <= len and str:sub(pos, pos):match("%s") do pos = pos + 1 end local value local char = str:sub(pos, pos) if char == "{" then -- Table lồng nhau value, pos = parse(str, pos + 1) if value == nil then return nil, pos end elseif char == "\"" or char == "'" then -- Chuỗi local quote = char pos = pos + 1 local start = pos while pos <= len and str:sub(pos, pos) ~= quote do if str:sub(pos, pos) == "\\" then pos = pos + 1 end pos = pos + 1 end if pos > len then return nil, "Unterminated string" end value = str:sub(start, pos - 1) pos = pos + 1 elseif char:match("%d") or char == "-" then -- Số local start = pos while pos <= len and str:sub(pos, pos):match("[0-9%.eE%+%-]") do pos = pos + 1 end value = tonumber(str:sub(start, pos - 1)) if value == nil then return nil, "Invalid number" end elseif str:sub(pos, pos + 3) == "true" then value = true pos = pos + 4 elseif str:sub(pos, pos + 4) == "false" then value = false pos = pos + 5 elseif str:sub(pos, pos + 2) == "nil" then value = nil pos = pos + 3 else return nil, "Invalid value" end t[key] = value -- Bỏ qua khoảng trắng trước dấu "," hoặc "}" while pos <= len and str:sub(pos, pos):match("%s") do pos = pos + 1 end -- Kiểm tra dấu "," hoặc "}" (cho phép "}" ngay sau giá trị) if pos <= len then local next_char = str:sub(pos, pos) if next_char == "," then pos = pos + 1 elseif next_char ~= "}" then return nil, "Expected ',' or '}'" end end end return t, pos end -- Gọi hàm phân tích và trả về kết quả local result, err = parse(str) if result == nil then return nil, err end -- Kiểm tra nếu table có đúng một phần tử là table, trả về phần tử đó local count = 0 local inner_table for _, v in pairs(result) do count = count + 1 if type(v) == "table" then inner_table = v else inner_table = nil break end end if count == 1 and inner_table then return inner_table end return result end