fork download
  1. -- Hàm chuyển chuỗi thành table
  2. function stringToTable(str)
  3. -- Loại bỏ khoảng trắng thừa ở đầu và cuối
  4. str = str:match("^%s*(.-)%s*$")
  5.  
  6. -- Kiểm tra nếu chuỗi rỗng hoặc không phải table
  7. if str == "" or str:sub(1, 1) ~= "{" or str:sub(-1) ~= "}" then
  8. return nil, "Invalid table string"
  9. end
  10.  
  11. -- Hàm phụ để phân tích chuỗi thành table
  12. local function parse(str, pos)
  13. local t = {}
  14. pos = pos or 1
  15. local len = #str
  16.  
  17. while pos <= len do
  18. -- Bỏ qua khoảng trắng
  19. while pos <= len and str:sub(pos, pos):match("%s") do
  20. pos = pos + 1
  21. end
  22.  
  23. -- Kết thúc table
  24. if pos > len then break end
  25. if str:sub(pos, pos) == "}" then
  26. return t, pos + 1
  27. end
  28.  
  29. -- Phân tích key
  30. local key
  31. if str:sub(pos, pos) == "[" then
  32. -- Key dạng [key]
  33. pos = pos + 1
  34. local start = pos
  35. local bracket_count = 1
  36. while pos <= len and bracket_count > 0 do
  37. if str:sub(pos, pos) == "[" then
  38. bracket_count = bracket_count + 1
  39. elseif str:sub(pos, pos) == "]" then
  40. bracket_count = bracket_count - 1
  41. end
  42. pos = pos + 1
  43. end
  44. if bracket_count ~= 0 then
  45. return nil, "Invalid key syntax"
  46. end
  47. local key_str = str:sub(start, pos - 2)
  48. key = load("return " .. key_str)()
  49. if key == nil then
  50. return nil, "Invalid key"
  51. end
  52. -- Bỏ qua dấu "="
  53. while pos <= len and str:sub(pos, pos):match("%s") do
  54. pos = pos + 1
  55. end
  56. if str:sub(pos, pos) ~= "=" then
  57. return nil, "Expected '=' after key"
  58. end
  59. pos = pos + 1
  60. else
  61. -- Key dạng identifier hoặc số thứ tự
  62. local start = pos
  63. while pos <= len and str:sub(pos, pos):match("[%w_]") do
  64. pos = pos + 1
  65. end
  66. key = str:sub(start, pos - 1)
  67. if key == "" then
  68. key = #t + 1
  69. else
  70. -- Bỏ qua dấu "="
  71. while pos <= len and str:sub(pos, pos):match("%s") do
  72. pos = pos + 1
  73. end
  74. if str:sub(pos, pos) ~= "=" then
  75. pos = start
  76. key = #t + 1
  77. else
  78. pos = pos + 1
  79. end
  80. end
  81. end
  82.  
  83. -- Phân tích value
  84. while pos <= len and str:sub(pos, pos):match("%s") do
  85. pos = pos + 1
  86. end
  87.  
  88. local value
  89. local char = str:sub(pos, pos)
  90.  
  91. if char == "{" then
  92. -- Table lồng nhau
  93. value, pos = parse(str, pos + 1)
  94. if value == nil then
  95. return nil, pos
  96. end
  97. elseif char == "\"" or char == "'" then
  98. -- Chuỗi
  99. local quote = char
  100. pos = pos + 1
  101. local start = pos
  102. while pos <= len and str:sub(pos, pos) ~= quote do
  103. if str:sub(pos, pos) == "\\" then
  104. pos = pos + 1
  105. end
  106. pos = pos + 1
  107. end
  108. if pos > len then
  109. return nil, "Unterminated string"
  110. end
  111. value = str:sub(start, pos - 1)
  112. pos = pos + 1
  113. elseif char:match("%d") or char == "-" then
  114. -- Số
  115. local start = pos
  116. while pos <= len and str:sub(pos, pos):match("[0-9%.eE%+%-]") do
  117. pos = pos + 1
  118. end
  119. value = tonumber(str:sub(start, pos - 1))
  120. if value == nil then
  121. return nil, "Invalid number"
  122. end
  123. elseif str:sub(pos, pos + 3) == "true" then
  124. value = true
  125. pos = pos + 4
  126. elseif str:sub(pos, pos + 4) == "false" then
  127. value = false
  128. pos = pos + 5
  129. elseif str:sub(pos, pos + 2) == "nil" then
  130. value = nil
  131. pos = pos + 3
  132. else
  133. return nil, "Invalid value"
  134. end
  135.  
  136. t[key] = value
  137.  
  138. -- Bỏ qua khoảng trắng trước dấu "," hoặc "}"
  139. while pos <= len and str:sub(pos, pos):match("%s") do
  140. pos = pos + 1
  141. end
  142.  
  143. -- Kiểm tra dấu "," hoặc "}" (cho phép "}" ngay sau giá trị)
  144. if pos <= len then
  145. local next_char = str:sub(pos, pos)
  146. if next_char == "," then
  147. pos = pos + 1
  148. elseif next_char ~= "}" then
  149. return nil, "Expected ',' or '}'"
  150. end
  151. end
  152. end
  153.  
  154. return t, pos
  155. end
  156.  
  157. -- Gọi hàm phân tích và trả về kết quả
  158. local result, err = parse(str)
  159. if result == nil then
  160. return nil, err
  161. end
  162.  
  163. -- Kiểm tra nếu table có đúng một phần tử là table, trả về phần tử đó
  164. local count = 0
  165. local inner_table
  166. for _, v in pairs(result) do
  167. count = count + 1
  168. if type(v) == "table" then
  169. inner_table = v
  170. else
  171. inner_table = nil
  172. break
  173. end
  174. end
  175. if count == 1 and inner_table then
  176. return inner_table
  177. end
  178.  
  179. return result
  180. end
Success #stdin #stdout 0.01s 5312KB
stdin
Standard input is empty
stdout
Standard output is empty