I have this pattern:
^u.meta(\.|$)
EXPECTED BEHAVIOUR
^u.meta(\.|$)
will match all the roles like:
u.meta
u.meta.admin
u.meta.admin.system
u.meta.*
Where as it should not match something like below:
u.meta_admin
u.meta_admin_system
I have tested this pattern with https://regex101.com/ online regexp tester
.
PROBLEM:
I have to implement this pattern with lua
script.
but getting invalid escape sequence near '\.'
:
-- lua script
> return string.match("u.meta.admin", '^u.meta(\.|$)')
stdin:1: invalid escape sequence near '\.'
And I tried adding double \\
as well as removing '\' escape char in that regexp but got nil in return:
-- lua script
> return string.match("u.meta.admin", '^u.meta(\\.|$)')
nil
> return string.match("u.meta.admin", '^u.meta(.|$)')
nil
See Lua regex docs:
The character %
works as an escape for those magic characters.
Also, the (...|...)
alternation is not supported in Lua. Instead, I guess, you need a word boundary here, like %f[set]
frontier pattern:
%f[set]
, a frontier pattern; such item matches an empty string at any position such that the next character belongs to set and the previous character does not belong to set. The set set is interpreted as previously described. The beginning and the end of the subject are handled as if they were the character \0
.
So, you can use
return string.match("u.meta.admin", '^u%.meta%f[%A]')
To only match at the end or before a .
:
return string.match("u.meta", '^u%.meta%f[\0.]')
To match only if the admin
is not followed with a letter or an underscore, use a negated character class [^%a_]
:
return string.match("u.meta_admin", '^u%.meta%f[[^%a_]]')
See IDEONE demo to check the difference between the two expressions.
print(string.match("u.meta", '^u%.meta%f[\0.]')) -- u.meta
print(string.match("u.meta.admin", '^u%.meta%f[\0.]')) -- u.meta
print(string.match("u.meta-admin", '^u%.meta%f[\0.]')) -- nil
print(string.match("u.meta", '^u%.meta%f[%A]')) -- u.meta
print(string.match("u.meta.admin", '^u%.meta%f[%A]')) -- u.meta
print(string.match("u.meta-admin", '^u%.meta%f[%A]')) -- u.meta
-- To exclude a match if `u.admin` is followed with `_`:
print(string.match("u.meta_admin", '^u%.meta%f[[^%a_]]')) -- nil
NOTE To match the end of the string, instead of \0
, you can safely use %z
(as @moteus noted in his comment) (see this reference):
%z
the character with representation 0