lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 27/02/2011 17:07, David Given wrote:
Does anyone have a cunning piece of pure-Lua code for argifying a
string? That is, turning this:

	foo bar "baz bloo \"fnord" wibble

into this:

	{'foo', 'bar', 'baz bloo "fnord', 'wibble'}

...?

I've had a look at the wiki, as this is a fairly stock problem, but
don't see anything.


I woudn't call the piece below "cunning", but it seems to work.

-- Split command line into separate arguments.
-- * The function does not raise errors: any input string is acceptable and
--   is split into arguments according to the rules below.
-- * An argument is:
--   a) sequence enclosed within a pair of non-escaped double quotes; can
-- contain spaces; enclosing double quotes are stripped from the argument. -- b) sequence containing non-space, non-unescaped-double-quote characters.
-- * Arguments of both kinds can contain escaped double quotes;
-- * Backslashes escape only double quotes; non-escaped double quotes either
--   start or end an argument.

function SplitCommandLine (str)
  local out = {}
  local from = 1
  while true do
    local to
    from = str:find("%S", from)
    if not from then break end
    if str:sub(from,from) == '"' then
      from, to = from+1, from+1
      while true do
        local c = str:sub(to,to)
        if c == '' or c == '"' then
          out[#out+1] = str:sub(from,to-1)
          from = to+1
          break
        elseif str:sub(to,to+1) == [[\"]] then to = to+2
        else to = to+1
        end
      end
    else
      to = from
      while true do
        local c = str:sub(to,to)
        if c == '' or c == '"' or c:find("%s") then break
        elseif str:sub(to,to+1) == [[\"]] then to = to+2
        else to = to+1
        end
      end
      out[#out+1] = str:sub(from,to-1)
      from = to
    end
  end
  for i,v in ipairs(out) do out[i]=v:gsub([[\"]], [["]]) end
  return out
end

--
Shmuel