lua 解析多个字节后的二进制数据

如何在多个字节后解析二进制数据? 例如:

56 30 30 31 07 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 01 45 7E 12 02 EF BF BD 00 EF BF BD 1F 56 30 30 31 01 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 02 45 24 56 30 30 31 04 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 02 45 13 00 00 00 56 30 30 31 07 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 01 45 7E 12 02 24 00 4D EF BF

我想在 0x56 0x30 0x30 0x31 后解析这段数据。在每个新的 0x56 0x30 0x30 0x31 前,旧的数据包(字符串)应该结束。

就像这样:

56 30 30 31 07 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 01 45 7E 12 02 EF BF BD 00 EF BF BD 1F

56 30 30 31 01 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 02 45 24

56 30 30 31 04 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 02 45 13 00 00 00

56 30 30 31 07 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 01 45 7E 12 02 24 00 4D EF BF

我已经针对一个字节后的解析做了一些类似的事情。但我不能将其转换为我的新问题。 这是解析 0x7E 后的代码示例:

function print_table(tab)
print("Table:")
for key, value in pairs(tab) do
  io.write(string.format("%02X ", value))
end
print("\n")
end

local function read_file(path, callback)
local file = io.open(path, "rb")
if not file then
 return nil
end
local t = {}
repeat
local str = file:read(4 * 1024)
for c in (str or ''):gmatch('.') do
    if c:byte() == 0x7E then
        callback(t) -- function print_table
        t = {}
    else
        table.insert(t, c:byte())
    end
end
until not str
file:close()
return t
end

local result = {}
function add_to_table_of_tables(t)
table.insert(result, t)
end

local fileContent = read_file("file.dat", print_table)

56 30 30 31 是首先写入字符串很重要。 感谢您的帮助!

我也需要从文件中读取输入,像这样读取我的文件:

local function read_file(path) --function read_file
  local file = io.open(path, "rb") -- r read mode and b binary mode
  if not file then return nil end
  local content = file:read "*all" -- *all reads the whole file
  file:close()
  return content
end
点赞
用户7396148
用户7396148

你可以使用gsub将目标子字符串替换为输入字符串中唯一的单个字符,这里我将使用\n作为示例。之后,您可以使用gmatch,其中它选择不是替换字符的一系列字符。

local input = [[56 30 30 31 07 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 01 45 7E 12 02 EF BF BD 00 EF BF BD 1F 56 30 30 31 01 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 02 45 24 56 30 30 31 04 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 02 45 13 00 00 00 56 30 30 31 07 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 01 45 7E 12 02 24 00 4D EF BF]]

local pattern ="([^\n]+)"
local rowPrefix = "56 30 30 31"

input = input:gsub(rowPrefix, "\n")

for row in input:gmatch(pattern) do
  print(rowPrefix .. row)
end

输出:

56 30 30 31 07 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 01 45 7E 12 02 EF BF BD 00 EF BF BD 1F
56 30 30 31 01 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 02 45 24
56 30 30 31 04 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 02 45 13 00 00 00
56 30 30 31 07 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 01 45 7E 12 02 24 00 4D EF BF

更多信息的资源:

在Lua中编程:20.1 - 模式匹配函数

Lua 5.3参考手册:string.gmatch

Lua 5.3参考手册:string.gsub

2021-03-16 14:08:29
用户107090
用户107090

将下面翻译成中文并且保留原本的 markdown 格式,

适应以下代码:

S=[[56 30 30 31 07 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 01 45 7E 12 02 EF BF BD 00 EF BF BD 1F 56 30 30 31 01 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 02 45 24 56 30 30 31 04 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 02 45 13 00 00 00 56 30 30 31 07 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 01 45 7E 12 02 24 00 4D EF BF]]
H=[[56 30 30 31]]
E="\n"
S=S:gsub(H,E..H)
S:gsub(E.."([^"..E.."]+)",print)
S=[[56 30 30 31 07 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 01 45 7E 12 02 EF BF BD 00 EF BF BD 1F 56 30 30 31 01 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 02 45 24 56 30 30 31 04 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 02 45 13 00 00 00 56 30 30 31 07 00 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 01 45 7E 12 02 24 00 4D EF BF]]
H=[[56 30 30 31]]
E="\n"
S = S:gsub(H,E..H) -- 以换行符开始
S:gsub(E.."([^"..E.."]+)",print) -- 分割成子字符串并打印
2021-03-16 14:14:32