lua-users home
lua-l archive

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


Hello,

What would be a reasonable way to, hmmm, quote unquoted tokens?

Say a token is an uninterrupted sequence of alphanumeric characters
(%w) or a quoted token. A quoted token is any sequence of characters
inside quotes, minus any quote characters.

For example:

'foo "hello world" bar'

How to turn the above into:

'"foo" "hello world" "bar"'

Thoughts?

You can do this in plain Lua but it's not nice, I would prefer LPeg:

----

lpeg = require 'lpeg'
whitespace = lpeg.S'\r\n\f\t '^1
unquoted = lpeg.R('AZ', 'az', '09')^1
single_quoted = "'" * (1 - lpeg.P"'")^0 * "'"
double_quoted = '"' * (1 - lpeg.P'"')^0 * '"'
any = lpeg.C(whitespace + unquoted + single_quoted + double_quoted)

function quote_tokens(input)
  local i = 1
  local output = {}
  while true do
    local match = any:match(input, i)
    if not match then
      break
    else
      i = i + #match
      if match:find '%S+' then
        if match:find '^[A-Za-z0-9]+$' then
          match = '"' .. match .. '"'
        end
        output[#output + 1] = match
      end
    end
  end
  return table.concat(output, ' ')
end

assert(quote_tokens 'foo bar baz' == '"foo" "bar" "baz"')
assert(quote_tokens 'foo "bar" baz' == '"foo" "bar" "baz"')
assert(quote_tokens "foo 'bar' baz" == '"foo" \'bar\' "baz"')

----

One notable advantage of LPeg is that it's dead easy to extend this example with support for escape sequences and stuff like that :-)

 - Peter