[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Literate Patterns
- From: RJ Russell <russellsprouts2@...>
- Date: Wed, 14 Jul 2010 09:11:02 -0700
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)