Lua 图案 - 魔兽世界原版

Lua Patterns - World of Warcraft Vanilla

我正在尝试从游戏聊天中获取一些数据,但我无法弄清楚其中的规律。

它用于魔兽世界原版(私人服务器)的附加组件。

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]+)?"实际上是我的多次尝试加在一起

我确实读到了 魔法字符 ( ) . % + - * ? [ ^ $,但还有一些我不明白。如果我能得到一份简单的简历说明就好了!

聊天外观的重要部分:

编辑():

问题:如何获取完整的“99d23h59m59s”(^(.*s)没成功)?

99d23h59m59s中,99可以是1到99,它后面总是有一个d,但如果实际上有一个<number>d,它是可选的.然后同理<number>h(数字取值范围为1~24),<number>m(数字取值范围为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()

信息更新:

Unlike several other scripting languages, Lua does not use POSIX regular expressions (regexp) for pattern matching. The main reason for this is size: A typical implementation of POSIX regexp takes more than 4,000 lines of code. This is bigger than all Lua standard libraries together. In comparison, the implementation of pattern matching in Lua has less than 500 lines. Of course, the pattern matching in Lua cannot do all that a full POSIX implementation does. Nevertheless, pattern matching in Lua is a powerful tool and includes some features that are difficult to match with standard POSIX implementations.

Source.

Unlike some other systems, in Lua a modifier can only be applied to a character class; there is no way to group patterns under a modifier. For instance, there is no pattern that matches an optional word (unless the word has only one letter). Usually you can circumvent this limitation using some of the advanced techniques that we will see later.

Source.

我找不到上面引用的“高级技术”。我只找到了 this,我还不确定。

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") 然后 print(d,h,m,s) 会说天数是 5,秒数是 25。相反,我们绝对确定输出的顺序。

我 运行 几年前使用 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 }