lua-users home
lua-l archive

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


I saw someone say something about Lua patterns being very terse and
confusing at first glance. I know I agree - I can't think of any
easily readable regex patterns, so I hacked together this code. It
adds a string.pattern field that is a literate programming interface.
I wouldn't really recommend using this code, as I built in a few
minutes, but it is good educationally.
The patterns are much longer, but a lot more readable I think.

--this code is public domain
local pattern=''
local classes={
  letters='%a',
  digits='%d',
  lowercase='%l',
  punctuation='%p',
  space='%s',
  uppercase='%u',
  alphanumeric='%w',
  word='%w',
  hex='%x',
  zero='%z',
  all='.',
  ['^']='%^',
  ['$']='%$',
  ['(']='%(',
  [')']='%)',
  ['%']='%%',
  ['.']='%.',
  ['[']='%[',
  [']']='%]',
  ['*']='%*',
  ['+']='%+',
  ['-']='%-',
  ['?']='%?',
}
local function patternize(arg)
  return classes[arg] or arg
end
do
end
local tab={}
local pathelper={
  set=function(...)
    local arg={...}
    for i,v in ipairs(arg) do
      arg[i]=patternize(v)
    end
    pattern=string.format('%s[%s]',pattern,table.concat(arg))
    return tab
  end,
  capture=setmetatable({},{__call=function(t,n)pattern=pattern..'%'..n
end,__index=function(t,k)pattern=pattern..'(' return tab[k] end}),
  endcapture=setmetatable({},{__index=function(t,k)pattern=pattern..')'
return tab[k] end}),
  capturepos=setmetatable({},{__index=function(t,k)pattern=pattern..'()'
return tab[k] end}),
  endpattern=function()local ret=pattern pattern='' return ret end,
  any=setmetatable({},{__call=function(t,v)
pattern=pattern..patternize(v)..'*' return tab
end,__index=function(t,k)pattern=pattern..'*' return tab[k] end}),
  maybe=setmetatable({},{__call=function(t,v)
pattern=pattern..patternize(v)..'?' return tab
end,__index=function(t,k)pattern=pattern..'?' return tab[k] end}),
  oneplus=setmetatable({},{__call=function(t,v)
pattern=pattern..patternize(v)..'+' return tab
end,__index=function(t,k)pattern=pattern..'+' return tab[k] end}),
  least=setmetatable({},{__call=function(t,v)
pattern=pattern..patternize(v)..'-' return tab
end,__index=function(t,k)pattern=pattern..'-' return tab[k] end}),
  balanced=function(a,b) pattern=pattern..'%b'..a..b return tab end,
  class=function(v)pattern=pattern..classes[v] return tab end,
}
string.pattern=tab
setmetatable(tab,{__index=pathelper})


--EXAMPLE USAGE
--%s*()([%$_%a][%$%w_]*)
local identifiers=string.pattern.
  any'space'.
  capturepos.
  capture.
    set('$','_','letters').
    set('$','_','word').any.
  endcapture.
endpattern()
string.find('  $hi',identifiers)