【问题标题】:Tokenizing string in (old) Lua在(旧)Lua 中标记字符串
【发布时间】:2020-06-18 01:06:33
【问题描述】:

我正在尝试使用 Lua 标记 NMEA 句子。当前的 Lua 版本(可在 https://www.lua.org/cgi-bin/demo 获得)按预期工作:

local index = 0
for token in string.gmatch("$HEHDT,99.00,,T*2F", "[%w.]*") do
 print(string.format("%d: %s", index, token))
 index = index + 1
end

给予:

0: 
1: HEHDT
2: 99.00
3: 
4: T
5: 2F
Your program ran successfully.

但是,使用 Lua 5.1.4(以及 Wireshark 中的 5.2.4)

0:
1: HEHDT
2:
3: 99.00
4:
5:
6: T
7:
8: 2F
9:

有没有办法使用旧 Lua 实现与使用当前版本相同的标记化输出?

【问题讨论】:

  • 如果没有真正成熟的正则表达式支持,这似乎是不可能的。
  • @WiktorStribiżew 在当前的 Lua 版本中没有成熟的正则表达式绝对是可能的 - 如第一个示例所示。我也在寻找在以前的版本中这样做的方法。
  • 这就是我的意思:在 5.4.2 中似乎不可能,空匹配的引擎行为已经改变。
  • @WiktorStribiżew - Lua 模式足够强大,因此在大多数情况下(IMO 95%)你不需要成熟的正则表达式。

标签: lua tokenize lua-patterns wireshark-dissector


【解决方案1】:
local index = 0
local str = "$HEHDT,99.00,,T*2F"
for token in string.gmatch(str.."$", "([%w.]*)[^%w.]") do
   print(string.format("%d: %s", index, token))
   index = index + 1
end

【讨论】:

  • 这对于很长的字符串不会表现不佳吗? (因为是串联,也就是)
  • @DarkWiiPlayer - 很难确定。请制定基准并分享结果。
  • 我将其标记为正确,因为它完成了工作。 NMEA句子的最大长度是82,所以我的表现很好。
【解决方案2】:

似乎 Lua 出于某种原因将两个标记之间的空字符串检测为单独的标记。这是不直观的,但并非完全错误,因为[%w]* 匹配空字符串。您可以通过使用 string.find 并在每次匹配后将位置增加 2 而不是 1 来解决此问题:

local index = 0
local str = "$HEHDT,99.00,,T*2F"

local a, b = 0, 1
while true do
  a, b = str:find("[%w.]*", b+2)
  if not a then break end
  print(string.format("%d: [%i,%i] %s", index, a, b, str:sub(a, b)))
  index = index + 1
end

该代码可能会被重写为更漂亮一点,但我会把它留给你 :D

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    • 2011-11-28
    • 2014-07-26
    • 2011-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多