Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

129 рядки
2.7 KiB

  1. R"(
  2. ------------------------------------------------------------------
  3. --
  4. -- Author: Alexey Melnichuk <alexeymelnichuck@gmail.com>
  5. --
  6. -- Copyright (C) 2016 Alexey Melnichuk <alexeymelnichuck@gmail.com>
  7. --
  8. -- Licensed according to the included 'LICENSE' document
  9. --
  10. -- This file is part of lua-split library.
  11. --
  12. ------------------------------------------------------------------
  13. ---
  14. -- @usage
  15. -- split = require "split"
  16. -- lines = split(str, '\r?\n')
  17. -- key, val = split.first(str, '=', true)
  18. -- a,b,c,d = split.unpack(str, ':', true)
  19. local unpack = unpack or table.unpack
  20. local function is_match_empty(pat, plain)
  21. return not not string.find('', pat, nil, plain)
  22. end
  23. local function split(str, sep, plain)
  24. local b, res = 0, {}
  25. sep = sep or '%s+'
  26. assert(type(sep) == 'string')
  27. assert(type(str) == 'string')
  28. if #sep == 0 then
  29. for i = 1, #str do
  30. res[#res + 1] = string.sub(str, i, i)
  31. end
  32. return res
  33. end
  34. assert(not is_match_empty(sep, plain), 'delimiter can not match empty string')
  35. while b <= #str do
  36. local e, e2 = string.find(str, sep, b, plain)
  37. if e then
  38. res[#res + 1] = string.sub(str, b, e-1)
  39. b = e2 + 1
  40. if b > #str then res[#res + 1] = "" end
  41. else
  42. res[#res + 1] = string.sub(str, b)
  43. break
  44. end
  45. end
  46. return res
  47. end
  48. local function split_iter(str, sep, plain)
  49. sep = sep or '%s+'
  50. assert(type(sep) == 'string')
  51. assert(type(str) == 'string')
  52. if #sep == 0 then
  53. local i = 0
  54. return function()
  55. i = i + 1
  56. if i > #str then return end
  57. return (string.sub(str, i, i))
  58. end
  59. end
  60. assert(not is_match_empty(sep, plain), 'delimiter can not match empty string')
  61. local b, eol = 0
  62. return function()
  63. if b > #str then
  64. if eol then
  65. eol = nil
  66. return ""
  67. end
  68. return
  69. end
  70. local e, e2 = string.find(str, sep, b, plain)
  71. if e then
  72. local s = string.sub(str, b, e-1)
  73. b = e2 + 1
  74. if b > #str then eol = true end
  75. return s
  76. end
  77. local s = string.sub(str, b)
  78. b = #str + 1
  79. return s
  80. end
  81. end
  82. local function usplit(...) return unpack(split(...)) end
  83. local function split_first(str, sep, plain)
  84. sep = sep or '%s+'
  85. assert(type(sep) == 'string')
  86. assert(type(str) == 'string')
  87. if #sep == 0 then
  88. return string.sub(str, 1, 1), string.sub(str, 2)
  89. end
  90. assert(not is_match_empty(sep, plain), 'delimiter can not match empty string')
  91. local e, e2 = string.find(str, sep, nil, plain)
  92. if e then
  93. return string.sub(str, 1, e - 1), string.sub(str, e2 + 1)
  94. end
  95. return str
  96. end
  97. return setmetatable({
  98. split = split;
  99. unpack = usplit;
  100. first = split_first;
  101. each = split_iter;
  102. },{
  103. __call = function(_, ...)
  104. return split(...)
  105. end
  106. })
  107. )"