问题描述
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 30BF 0BD 0EF 0BD EF 0BD 03 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 30BF 0BF 0BF 0BF 0BF 0 0BF 0 30BF 30BF 3 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
我已经做了一些类似的事情来解析一个字节到一个表中。但我不能把它变成我的新问题。 这就是1Byte 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
获取更多信息的资源:
Programming in Lua: 20.1 – Pattern-Matching Functions
Lua 5.3 Reference Manual: string.gmatch
Lua 5.3 Reference Manual: string.gsub
,修改此代码:
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)