lua-users home
lua-l archive

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


Awesome thanks, reading your examples really helps me grasping most of the core ideas of LPeg and re!!

> On Jul 11, 2017, at 20:51, Duncan Cross <duncan.cross@gmail.com> wrote:
> 
> On Sat, Jul 8, 2017 at 8:12 PM, Matthias Dörfelt <lists@mokafolio.de> wrote:
>> I tried to do so using table and named group capture, but I can’t for the
>> life of me figure out how to dynamically set the name of the group capture.
>> Will I have to write a custom helper function to achieve this or is there a
>> pure re way?
> 
> You do need to use a function for this -- re is only a thin layer on
> top of the same basic primitives as lpeg itself, and lpeg.Cg() takes a
> constant value, not a pattern capture, for the group name specifier.
> 
> One approach is to capture an array of key/value pair objects, and
> then use a function capture to transform this array into an object
> with named fields. Something like this:
> 
> --
> local re = require 're'
> 
> local fields = re.compile([[
>  fields <- {| <kvpair>* !. |} -> kvpairs_to_fields
> 
>  kvpair <- {| %s* {:key: <key> :} %s* '=' %s* {:value: <value> :} %s* |}
>  key <- [a-zA-Z_] [a-zA-Z_0-9]*
>  value <- <single_quoted> / <double_quoted>
>  single_quoted <- ['] { [^']* } [']
>  double_quoted <- ["] { [^"]* } ["]
> ]], {
>  kvpairs_to_fields = function(kvpairs)
>    local attrs = {}
>    for _, kv in ipairs(kvpairs) do
>      attrs[kv.key] = kv.value
>    end
>    return attrs
>  end;
> })
> 
> for k,v in pairs(fields:match[[ a="one" b = 'two' c="three" ]]) do
>  print(k, v)
> end
> --
> 
> -Duncan
> 
>