lua-users home
lua-l archive

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


On Mon, Sep 9, 2019 at 11:22 PM Sean Conner <sean@conman.org> wrote:
>
>   Normally I reach for LPEG to handle my parsing chores, but I have a
> project where that ... well, I'd be reimplementing a form of regex anyway,
> so why not use Lua patterns and avoid that mess.
>
>   But I have an issue that I do not know the answer to---I suspect there
> isn't an answer but "use a real regex or LPEG".  But I thought I would ask
> anyway.
>
>   I have a pattern that looks like this BNF:
>
>         TEXT    = 'A' - 'Z' / 'a' - 'z'
>         DIGIT   = '0' - '9'
>
>         pattern = 1*TEXT [ ';' 1*DIGIT ]
>
>   In English, text, optionally followed by a semicolon and some digits.  So
> some valid examples:
>
>         foo
>         foo;1
>         foo;444
>
>   Invalid examples are
>
>         foo;
>         foo23
>
>   If there's a semicolon, it must be followed by a digit; if there's no
> semicolon, no digits.  This is trivial (to me) in LPEG.  No so with Lua
> patterns.  There's:
>
>         "%a%;?(%d+)
>
> but that allows "foo23" to slip through.  What I would like would be:
>
>         %a(%;(%d+))?
>
> although that doesn't work, since the '?' can (if I'm reading the
> documentation right) only follow a character class, not a grouping.

Correct.

>   Am I missing something?
>
>   -spc (I mean, besides "using LPEG"?)

I feel like the typical way of doing this kind of thing in Lua is a
two-step process.

Untested example:

result = teststr:match "%a(%;?%d*)"

if result then
    if #result == 0 then
        print "match with no semicolon or number"
    elseif result:match "%;%d+" then
        print "match with semicolon and number"
    else
        print "no match (semicolon without number or vice versa)"
    end
else
    print "no match"
end

Adjust to suit your specific needs.