lua-users home
lua-l archive

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



On 22-Oct-05, at 12:36 PM, Rici Lake wrote:

(you could also use a function instead, after all.)

Here's a function you could just use (except that it doesn't handle %0; you'd need to surround the pattern with () if you wanted to capture the whole match):

---- CUT HERE ----
#!/usr/bin/env lua51

do
  local function makecapturefunc(str)
    local bodybuf = StringBuf()
    local maxcapture = "0"
    local f = str:gsub("([^%%]*)%%([%%1-9])",
                       function(prefix, capture)
                         if capture == "%" then
bodybuf:append(("%q"):format(prefix..capture))
                         else
                           if prefix ~= "" then
                             bodybuf:append(("%q"):format(prefix))
                           end
                           bodybuf:append("(a"..capture.." or '')")
if capture > maxcapture then maxcapture = capture end
                         end
                          return "" -- :)
                       end)
    if f ~= "" then
      bodybuf:append(("%q"):format(f))
    end
    local parmbuf = StringBuf()
    for i = 1, maxcapture do parmbuf:append(i) end

    return loadstring("return function(a"
                          .. table.concat(parmbuf, ", a")
                          .. ") return "
                      .. table.concat(bodybuf, "..")
                      .. " end")()
  end

  -- You probably don't want to go to all that work every time,
  -- so we'll export it memoized (although there is a risk of
  -- leaking memory since strings aren't weak in weak-keyed
  -- tables.)

  local memo = memoize(makecapturefunc)
  function string:gcapture() return memo[self] end
end

if arg then
  print((arg[1]:gsub(arg[2], arg[3])))
  print((arg[1]:gsub(arg[2], arg[3]:gcapture())))
end

---- Quick test:
$ ./capturef.lua "australia is a country i would like to see" "([aeiou])([aeiou])" "<Dipthong <Dipthong: u a>stral<Dipthong: a i> is a c<Dipthong: u o>ntry i w<Dipthong: u o>ld like to s<Dipthong: e e> <Dipthong: u a>stral<Dipthong: a i> is a c<Dipthong: u o>ntry i w<Dipthong: u o>ld like to s<Dipthong: e e>

--- The referenced library functions: ---

function memoize(func, t)
  return setmetatable(t or {}, {
    __index = function(t, key)
      local v = func(key)
      t[key] = v
      return v
    end})
end

do
  local concat = table.concat
  local stringbuf = {}
  function stringbuf:append(s)
    self[#self + 1] = s
  end
  function stringbuf:__tostring()
    return concat(self)
  end
  function stringbuf:concat(sep)
    return concat(self, sep)
  end
  stringbuf.__index = stringbuf

  function StringBuf()
    return setmetatable({}, stringbuf)
  end
end