parsing - 超过一个字节后的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 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 5 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
解决方案
您可以使用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
更多信息的资源:
推荐阅读
- docusignapi - Docusign API - 为 HTML 文档设置边距
- node.js - 函数中的Nodejs更新请求不起作用
- c++ - 无法在 Windows 10 上将 CLion 链接到 QT
- xml - 在 Golang 中的数组的情况下,XML Unmarshalling 属性不同
- sql - 用 SQL 比较 2 个表的记录
- php - PHP停止会话结束/注销用户
- jquery - jQuery获取页面上选择的所有单选按钮的ID并将它们分配给变量
- r - 过滤时间序列中的所有列以仅保留前 1/3
- c# - C# 控制台应用程序打印当前月份的数据
- java - 在 Java 客户端应用程序中实现 PUT