[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Patterns
- From: Sean Conner <sean@...>
- Date: Wed, 14 Dec 2022 21:36:03 -0500
It was thus said that the Great Paul Ducklin once stated:
> Why try to convert the matching string into a regexp or Lua pattern at
> all? Sometimes regexp-type code is simply the wrong way to do things, but
> something we do merely from familiarity.
>
> It sounds as though matching an input string X against the expression
> “/sport/#” in the fashion you describe is equivalent to:
>
> X == “/sport” or X:sub(1,7) == “/sport/“
>
> So why not just do it like that, and sidestep regexps, patterns,
> wildcards, state machines, and all that complexity? The code above is
> simpler, faster and self-documenting…
That actually might be simpler. Proof of concept:
local function match(pattern,target)
-- --------------------------------------------
-- I couldn't think of a better way to do this
-- --------------------------------------------
if pattern:match("#") and not pattern:match("#$") then
error "bad pattern"
end
local pf,ps,pc = pattern:gmatch "[^/]*" -- capture values from iterator
local tf,ts,tc = target:gmatch "[^/]*"
while true do
local pv = pf(ps,pc) -- get next segment in pattern
local tv = tf(ts,tc) -- get next segment in target
-- ---------------
-- if we're at the end of the pattern, we should be at the end
-- of the target
-- ---------------
if not pv then
return not tv
-- ----------------------------------------------------------------------
If the patttern segment is '+', then the target is an automatic match
-- ----------------------------------------------------------------------
elseif pv == '+' then
-- nothing to do here
-- -----------------------------------------------------
-- If the pattern is '#', then everything else matches
-- -----------------------------------------------------
elseif pv == '#' then
return true
-- ------------------------------------------------------
-- compare the two segments, if unequal, result is false
-- ------------------------------------------------------
else
if pv ~= tv then
return false
end
end
end
end
local function test(p,t)
print(match(p,t),p,t)
end
test("sport/tennis/player1/#","sport/tennis/player1")
test("sport/tennis/player1/#","sport/tennis/player1/ranking")
test("sport/tennis/player1/#","sport/tennis/player1/score/wimbleton")
test("sport/tennis/+","sport/tennis/player1")
test("sport/tennis/+","sport/tennis/player2")
test("sport/tennis/+","sport/tennis/player1/ranking")
test("+/tennis/#","news/tennis")
test("+/tennis/#","news/tennis/mcenroe")
test("+/tennis/#","/tennis/mcenroe")
test("+/tennis/#","sports/tennis/williams")
test("+/tennis/#","sports/tennis/williams/ranking")
test("+/tennis/#","tennis")
test("+/tennis/#","game/fussbol")
test("+/+","/finance")
test("/+","/finance")
test("/sport/#","/sport")
test("/sport/#","/sport/racing")
test("/sport/#","/sport/racing/champion")
test("/sport/#","/sporting")
-spc