Lua Patterns - 魔兽世界香草

时间:2017-02-10 21:18:01

标签: lua lua-patterns world-of-warcraft

我试图从游戏聊天中获取一些数据,但我无法弄清楚这种模式。

适用于魔兽世界香草(私人服务器)的AddOn。

gsub功能:
http://wowprogramming.com/docs/api/gsub
http://wowwiki.wikia.com/wiki/API_gsub

我在this解释方面做得很好,但现在我有一个这样的部分:

variable = gsub(string, "([%d+d]+)?...", "")

我不知道模式应该是什么,因为字符串可以像以下示例中的一样:

2d17h6m31s
1d8h31m40s
22h40m4s
8h6m57s
5m25s
37s

"([%d+d]+)?"实际上是我的多次尝试。

我确实读过关于魔术角色 ( ) . % + - * ? [ ^ $的内容,但还有一些我不明白的内容。如果我能得到简单的简历说明那就太棒了!

聊天的重要部分:

chat

编辑(ktb's comment):

问题:我怎样才能完整的" 99d23h59m59s" (^(.*s)没有做到这一点)?

99d23h59m59s中,99可以是1到99,并且它后面总是有d但如果实际上是{<number>d则可选是{1}}。然后相同于<number>h(数字范围从1到24),<number>m(数字&#39; s范围从1到59)。最后总是一个ago

更新

/run for key in pairs(string)do ChatFrame1:AddMessage(key)end

使用该命令,我获得了string.functionName()的所有函数名称,这里是列表:

  

string.sub()

     

string.gfind()

     

string.rep()

     

string.gsub()

     

string.char()

     

string.dump()

     

string.find()

     

string.upper()

     

string.len()

     

string.format()

     

string.byte()

     

string.lower()

信息更新:

  

与其他几种脚本语言不同,Lua不使用POSIX正则表达式(regexp)进行模式匹配。主要原因是尺寸:POSIX regexp的典型实现需要超过4,000行代码。这比所有Lua标准库一样大。相比之下,Lua中模式匹配的实现少于500行。当然,Lua中的模式匹配不能完全完成POSIX实现。然而,Lua中的模式匹配是一个强大的工具,包括一些难以与标准POSIX实现匹配的功能。

Source

  

与其他系统不同,在Lua中,修饰符只能应用于字符类;无法在修饰符下对模式进行分组。例如,没有与可选单词匹配的模式(除非单词只有一个字母)。通常,您可以使用我们稍后会看到的一些高级技术来规避此限制。

Source

我无法找到&#34;先进技术&#34;在上面的引文中说。我只发现this,我还不确定。

2 个答案:

答案 0 :(得分:3)

function get_time_stamp(str)
    local s,m,h,d = string.match(str:reverse(),"oga s(%d*)m?(%d*)h?(%d*)d?(%d*)")
    return d and d:reverse() or 0, h and h:reverse() or 0, m and m:reverse() or 0, s and s:reverse() or 0
end 
local day,hour,minute,second = get_time_stamp("2d17h6m31s ago")
print (day,hour,minute,second) -- output: 2 17 6 31

day,hour,minute,second = get_time_stamp("5m25s ago")
print (day,hour,minute,second) -- output: 0 0 5 25

如果你想知道为什么我使用反向,那是因为我们肯定知道第二个将永远存在但其他人不会,如果我们不使用反向那么我们将不知道数字在输出时的顺序通过string.match。这是我的意思,如果你做了local d,h,m,s = string.match("5m25s ago","(%d*)d?(%d*)h?(%d*)m?(%d+)s ago")然后打印(d,h,m,s)就会说天数是5秒,而25则是25.相反,我们绝对确定输出的顺序。< / p>

答案 1 :(得分:2)

几年前我用WoW插件遇到了相同的模式限制。它需要一些搜索,但我挖出了我的解析功能。

<强> parse_duration.lua

--
-- string:parseDuration() - parse a pseudo ISO-8601 duration of the form
-- [nd][nh][nm][ns], where 'n' is the numerical value of the time unit and
-- suffix designates time unit as follows: 'd' - days, 'h' - hours,
-- 'm' - minutes, and, 's' - seconds. Unspecified time units have a value
-- of 0.
--

function string:parseDuration()
  local ts = {d=0, h=0, m=0, s=0}
  for v in self:lower():gfind("%d+[dhms]") do
    ts[v:sub(-1)] = tonumber(v:sub(1,-2))
  end

  return ts
end

以下测试您的样本数据。

<强> duration_utest.lua

require "parse_duration"

local function main()
  local testSet = {
    "2d17h6m31s ago something happened",
    "1d8h31m40s ago something happened",
    "22h40m4s ago something happened",
    "8h6m57s ago something happened",
    "5m25s ago something happened",
    "37s ago something happened",
    "10d6s alias test 1d2h3m4s should not be parsed"
  }

  for i,testStr in ipairs(testSet) do
    -- Extract timestamp portion
    local tsPart = testStr:match("%S+")
    local ts = tsPart:parseDuration()

    io.write( tsPart, " -> { ")
    for k,v in pairs(ts) do
      io.write(k,":",v," ")
   end
    io.write( "}\n" )
  end
end

main()

<强>结果

2d17h6m31s -> { m:6 d:2 s:31 h:17 }
1d8h31m40s -> { m:31 d:1 s:40 h:8 }
22h40m4s -> { m:40 d:0 s:4 h:22 }
8h6m57s -> { m:6 d:0 s:57 h:8 }
5m25s -> { m:5 d:0 s:25 h:0 }
37s -> { m:0 d:0 s:37 h:0 }
10d6s -> { m:0 d:10 s:6 h:0 }