lua-users home
lua-l archive

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


On Sun, Feb 27, 2011 at 17:12, Reuben Thomas <rrt@sc3d.org> wrote:
> On 27 February 2011 15:07, David Given <dg@cowlark.com> wrote:
>>
>> I've had a look at the wiki, as this is a fairly stock problem, but
>> don't see anything.
>
> OK, I bite. I use Lua regularly, and almost exclusively for
> command-line programming, and I've never needed to "argify" a string
> (nice word, though). What's it for?
>
> --
> http://rrt.sc3d.org
>
>

Here's mine. I had the audacity to modify the string library but of
course you can name it however you like. Consider this code public
domain.

--[[ Splits a string into quoted chunks, performing C-style backslash escapes.
Inputs:
-str: String to split.
Returns: table of string segments.
Notes:
-The returned table is composed of pairs, such that every second element was
 quoted in the original string, and every other (i.e. odd-indexed) was not.
 If there are quotes at the beginning or end of a string or two quoted strings
 up against eachother, this will result in empty strings in the table, since
 the non-quoted portion of that chunk is empty. ]]
function string.splitquoted(str)
	local ret = {}
	local last, start = 1, 1
	
	--backslash escapes
	local repl = {["\\a"] = "\a", ["\\b"] = "\b", ["\\f"] = "\f", ["\\n"] ="\n",
		["\\r"] = "\r", ["\\t"] = "\t", ["\\v"] = "\v", ["\\\\"] = "\\"}
	local function dochr(str) return string.char(str:sub(2)) end
	local function addstr(str)
		local s = str:gsub("\\.", repl):gsub("\\%d%d*%d*", dochr)
		table.insert(ret, s)
	end
	
	while true do
		--Find quote
		local pos = str:find('\"', start, true)
		if not pos then addstr(str:sub(last)) break end --add last chunk
		
		--seek back to count backslashes to see if the quotes are escaped
		local esc = false
		local idx = pos - 1
		while (idx >= last) and (str:sub(idx, idx) == '\\') do
			esc, idx = not esc, idx - 1
		end
		
		if esc then start = pos + 1 --if escaped, just move on to next one
		else --else split here
			addstr(str:sub(last, pos - 1))
			last, start = pos + 1, pos + 1
		end
	end
	return ret
end

-- 
Sent from my toaster.