Pattern ^u.meta(\.|$) not working as expected

跟風遠走 提交于 2019-12-11 01:41:40

问题


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

回答1:


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



来源:https://stackoverflow.com/questions/35012081/pattern-u-meta-not-working-as-expected

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!