在(旧)Lua 中标记字符串

Tokenizing string in (old) Lua

我正在尝试使用 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 实现与使用当前版本相同的标记化输出?

似乎 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

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