Button Button Button

Previous Next

Lua doesn't have a string.split() function and most of the time you don't really need it because string.gmatch() is enough. However string.gmatch() has one significant disadvantage for me: You can't split a string while matching both the delimited strings and the delimiters themselves without tracking positions and substrings. The string_gsplit() function below takes care of this problem.

Author: Peter Odding

License: MIT/X11 Tags: strings patterns matching coroutines

Snippet

function string_gsplit(string, pattern, capture)
 string = string and tostring(string) or ''
 pattern = pattern and tostring(pattern) or '%s+'
 if (''):find(pattern) then
  error('pattern matches empty string!', 2)
 end
 return coroutine.wrap(function()
  local index = 1
  repeat
   local first, last = string:find(pattern, index)
   if first and last then
    if index < first then coroutine.yield(string:sub(index, first - 1)) end
    if capture then coroutine.yield(string:sub(first, last)) end
    index = last + 1
   else
    if index <= #string then coroutine.yield(string:sub(index)) end
    break
   end
  until index > #string
 end)
end

Tests/Usage

-- I recently needed this function to implement
-- version sorting. I wanted to split filenames
-- on decimal integers while preserving the numbers:

> for s in string_gsplit('LuaJIT-2.0.0-beta8.zip', '%d+', true) do
>> print(string.format('%q', s))
>> end
"LuaJIT-"
"2"
"."
"0"
"."
"0"
"-beta"
"8"
".zip"

Related Snippets


Revision 000001 by Peter Odding; created Sun, 11 Sep 2011 13:34:52 +0000

0 comments

Add a Comment