lua 超过一个字节后解析

lua parsing after more than one byte

如何解析超过一个字节的二进制文件? 例如:

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

我已经做了一些类似的事情来将一个字节后的内容解析为 table。但我不能把它变成我的新问题。 那就是一个Byte 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 to replace the target substring with a single char unique to the input string, I will use \n for this example. after that you can use 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)