【问题标题】:Pattern ^u.meta(\.|$) not working as expected模式 ^u.meta(\.|$) 未按预期工作
【发布时间】:2016-01-26 10:49:10
【问题描述】:

我有这个模式:

^u.meta(\.|$)

预期行为

^u.meta(\.|$) 将匹配所有角色,例如:

u.meta
u.meta.admin
u.meta.admin.system
u.meta.*

因为它不应该与下面的内容匹配:

u.meta_admin
u.meta_admin_system

我已经用https://regex101.com/在线regexp tester测试了这个模式。

问题:

我必须用lua 脚​​本来实现这个模式。 但得到invalid escape sequence near '\.':

-- lua script

> return  string.match("u.meta.admin", '^u.meta(\.|$)')
stdin:1: invalid escape sequence near '\.'

我尝试在该正则表达式中添加 double \\ 以及删除 '\' 转义字符,但得到 nil 作为回报:

-- lua script

> return string.match("u.meta.admin", '^u.meta(\\.|$)')
nil

> return  string.match("u.meta.admin", '^u.meta(.|$)')
nil

【问题讨论】:

  • 您需要使用% 而不是\。使用^u%.meta(%.|$)
  • @WiktorStribiżew:感谢您的快速回复,我正在测试该正则表达式
  • return string.match("u.meta.admin", '^u%.meta(%.|$)') 仍然返回nil :(
  • 是的,因为不支持(%.|$)。你在这里的意图是什么?您想确保 meta 是一个完整的单词(后跟一个非单词字符?)。试试print(string.match("u.meta.admin", '^u%.meta%f[%A]'))
  • 我会试一试的。我的意图是因为我在 qustion 中更新了Expected Behaviouru.meta 应与 u.meta.* 之类的任何内容匹配,包括 u.meta

标签: lua lua-patterns


【解决方案1】:

Lua regex docs:

角色% 充当这些魔法角色的转义符。

另外,Lua 不支持 (...|...) 替换。相反,我猜你需要一个词边界,比如%f[set] frontier pattern:

%f[set],前沿模式;这样的项目在任何位置匹配一个空字符串,使得下一个字符属于集合而前一个字符不属于集合。集合集合如前所述解释。主题的开头和结尾被当作字符\0处理。

所以,你可以使用

return string.match("u.meta.admin", '^u%.meta%f[%A]')

只匹配.的末尾或之前:

return string.match("u.meta", '^u%.meta%f[\0.]')

要仅在 admin 后面没有字母或下划线时匹配,请使用否定字符类 [^%a_]

return string.match("u.meta_admin", '^u%.meta%f[[^%a_]]')

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

注意要匹配字符串的结尾,而不是\0,您可以安全地使用%z(如@moteus noted in his comment)(参见this reference):

%z    代表0的角色

【讨论】:

  • return string.match("u.meta.admin", '^u%.meta%f[%A]') 正在工作,现在我不希望 u.meta_admin 匹配此正则表达式,仅匹配 u.meta.* 包括 u.meta,注意 dot(.) 字符和 underscore (_)
  • 然后尝试否定字符类方法:string.match("u.meta_admin", '^u%.meta%f[[^%a_]]') - 匹配 u.meta 仅当后面没有字母和 _ 时。
  • thanksprint(string.match("u.meta", '^u%.meta%f[\0.]')) 正在工作 +1
  • 只是一点小提示。 \0 仅从 Lua 5.2 开始允许。在 Lua 5.1 上,您需要使用 %z。这是如果您需要与旧的 Lua 版本兼容。
  • @moteus:是的,不知怎的,我没有注意到。当然%z 是一种方法:%z 代表0的角色
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-20
相关资源
最近更新 更多