【问题标题】:Pattern not matching *(%(*.%))模式不匹配 *(%(*.%))
【发布时间】:2017-03-11 22:12:09
【问题描述】:

我正在尝试从 reference manual 了解模式(在 string.gmatch 等中实现)如何在 Lua 5.3 中工作。

(感谢 @greatwolf 纠正我对使用 * 的模式项的解释。)

我要做的是匹配'(%(.*%))*'(由括起来的子字符串;例如'(grouped (etc))'),以便它记录

(分组(等))
(等)

分组(等)
等等

但它什么也没做???? (online compiler)。

local test = '(grouped (etc))'

for sub in test:gmatch '(%(.*%))*' do
    print(sub)
end

【问题讨论】:

  • 你为什么写*.而不是.*
  • @EgorSkriptunoff 我想匹配 ( 和 ) 之间的所有内容,根据手册,这是一个模式项,其中字符类必须跟随 * (在这个“跟随”术语中我理解,“在 * 之后声明”)。我认为.\* 最终会使用下一个字符类(在问题示例中,%%)),与.*% 相同,我猜。
  • 你错了,所有这些重复字符*-+ 等都出现在您要匹配的字符类之后。例如匹配字母使用%a*.* 将贪婪匹配任何字符。您的示例仅使用 * kleene 星,但之前没有任何内容,因此格式不正确。
  • @greatwolf 感谢您的更正,英语不是我的主要语言,所以我可能无法正确阅读。虽然葡萄牙语有时很相似!
  • 对于您的示例,您可以尝试%a+%s(%(.-%)),这意味着匹配 1 个或多个字母(不区分大小写)后跟可选空格,后跟 ( ) 中的任何字符。在匹配时捕获括号中的内容。

标签: lua lua-patterns


【解决方案1】:

另一种可能性——使用递归:

function show(s)
  for s in s:gmatch '%b()' do
    print(s)
    show(s:sub(2,-2))
  end
end

show '(grouped (etc))'

【讨论】:

  • 超级好的解决方案,我只是不太了解这个子。
  • :sub(2,-2) 只是在将其传递给下一个调用之前删除外括号,否则递归将永远不会终止。
  • 我明白了,我已经测试过了……非常好
【解决方案2】:

我认为您不能使用 gmatch 执行此操作,但使用 %b()while 循环可能会起作用:

local pos, _, sub = 0
while true do
  pos, _, sub  = ('(grouped (etc))'):find('(%b())', pos+1)
  if not sub then break end
  print(sub)
end

这将为我打印您的预期结果。

【讨论】:

  • 感谢您的想法,我在操作一些小东西时也做过类似的事情。但是,我有点困惑为什么它不能在 gmatch() 中使用 * :/
【解决方案3】:
local test = '(grouped (etc))'

print( test:match '.+%((.-)%)' )

这里:

。 +%( 捕获最大字符数,直到它 %( 即直到包含它的最后一个括号,其中 %( 只是转义括号。

(.-)%) 会将您的子字符串返回到第一个转义括号 %)

【讨论】:

  • 不幸的是它不匹配 'grouped (etc)''(grouped (etc))' :/,但无论如何谢谢(我已经尝试分组)。另外,我已将 .+ 更改为 .*.
  • 为什么不呢,你需要 catch 'etc'?
  • 我确实想匹配字符串中的每个组(这将是由 () 包围的子字符串),甚至是嵌套的。我最后一次尝试使用您的模式和gmatch()for sub in ('(grouped (etc))'):gmatch '.*%((.-)%)' do print(sub) end,当将整个字符类分组到模式项* 时,它什么也不做:'(.*%((.-)%))*',并且只在没有模式项的情况下分组,它只打印准确的'(grouped (etc)',但我不太关心括号,因为我正在学习(保留:'(.*%((.*)%))')。
  • 请显示完整示例(您的文本),然后获得完整答案
  • code online,你需要吗?
猜你喜欢
  • 1970-01-01
  • 2019-03-31
  • 1970-01-01
  • 2017-11-13
  • 2021-05-22
  • 1970-01-01
  • 2014-02-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多