3

I have strings like "ABC-DEF" and I need to split them by the "-" character and assign each of the two parts to a variable. In Ruby, I would do it like:

a, b = "ABC-DEF".split('-')

Apparently, Lua doesn't have such an easy way. After some digging, I couldn't find a short and concise way to achieve what I'm after. I mention I am a complete newbie to Lua and I need to use it in a script for Redis (so it should indeed be small, a one liner if possible).

linkyndy
  • 17,038
  • 20
  • 114
  • 194

2 Answers2

11

Use pattern matching:

a, b = string.match("ABC-DEF", "(.*)%-(.*)")

Note that - is a magic character, so it must be escaped with %.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
2

Although you can certainly do it as suggested by Yu Hao, if you need a general library that you can use with Python-like simplicity, the code below will give you just that. It will also give you a gsplit() iterator.

local unpack = table.unpack or unpack

--------------------------------------------------------------------------------
-- Escape special pattern characters in string to be treated as simple characters
--------------------------------------------------------------------------------

local
function escape_magic(s)
  local MAGIC_CHARS_SET = '[()%%.[^$%]*+%-?]'
  if s == nil then return end
  return (s:gsub(MAGIC_CHARS_SET,'%%%1'))
end

--------------------------------------------------------------------------------
-- Returns an iterator to split a string on the given delimiter (comma by default)
--------------------------------------------------------------------------------

function string:gsplit(delimiter)
  delimiter = delimiter or ','          --default delimiter is comma
  if self:sub(-#delimiter) ~= delimiter then self = self .. delimiter end
  return self:gmatch('(.-)'..escape_magic(delimiter))
end

--------------------------------------------------------------------------------
-- Split a string on the given delimiter (comma by default)
--------------------------------------------------------------------------------

function string:split(delimiter,tabled)
  tabled = tabled or false              --default is unpacked
  local ans = {}
  for item in self:gsplit(delimiter) do
    ans[ #ans+1 ] = item
  end
  if tabled then return ans end
  return unpack(ans)
end
tonypdmtr
  • 3,037
  • 2
  • 17
  • 29