Lua读取INI文件:提取偶数行竖线右侧内容的问题
Lua处理INI文件提取内容问题
我不是Lua开发者,但偶尔要处理相关任务,遇到了下面的问题:
我有一个纯文本格式的INI文件,每个配置项以两行形式编写,格式如下:
[machine_readable_plugin_name] (plugin_name.maker.tld),flag=0|Human Readable Plugin Name (Maker)
文件里包含几百组上述格式的行对,我需要:
- 忽略所有包含
[]的第一行,不用保留其内容 - 从第二行中提取竖线
|之后的内容
我尝试用print(string.match(s, "|(.*)"))提取,但返回空字符串。变量s是通过FOR循环读取的文件行,用print(s)可以正常打印所有行。
我需要的输出是每组行对对应一行:
Human Readable Plugin Name (Maker)
如果INI文件有20行,应该输出10条类似内容:
Human Readable Plugin 1 Name (Maker 1) Human Readable Plugin 2 Name (Maker 2) Human Readable Plugin 3 Name (Maker 3) ... Human Readable Plugin 10 Name (Maker 10)
注:这个INI文件是随应用程序附带的,我没法修改它的格式。
编辑1
以下是我写的代码:
local path_ = 'K:/APP_NAME/settings-win64.ini' local handle_ = io.open(path_, "r") for _ in handle_:lines() do s = handle_:read("*l") print(s) -- 这里输出正常,所有行都能打印出来 if _ == nil then handle_:close() else if s ~= nil then human_Name = string.match(s, "|(.+)$") print("TEST") -- 这里能按预期打印 print(s) -- 这里也能正常打印 print(human_Name) -- 这里是空的,什么都打不出来 end end -- if 1 end -- for
问题分析与解决方案
你的代码存在两个核心问题:
- 读取逻辑冲突:
handle_:lines()已经在逐行遍历文件,循环内部又调用handle_:read("*l"),这种混合读取方式容易导致行顺序错位或读取异常; - 匹配容错性不足:
|(.+)$要求|后内容直达行尾,但如果行尾有隐藏空白字符(如换行符、空格),会导致匹配失败。
下面是两种可靠的解决代码:
方案1:逐行判断处理
直接遍历每一行,跳过带[]的行,对目标行提取内容:
local path_ = 'K:/APP_NAME/settings-win64.ini' local handle_ = io.open(path_, "r") if handle_ then -- 逐行读取文件 for line in handle_:lines() do -- 判断是否是带[]的配置行,是的话跳过 if not line:match("%[.*%]") then -- 提取|之后的所有内容 local human_Name = line:match("|(.+)") if human_Name then print(human_Name) end end end handle_:close() end
方案2:两行一组处理
严格按照两行一组的格式读取,第一行直接忽略,第二行提取内容:
local path_ = 'K:/APP_NAME/settings-win64.ini' local handle_ = io.open(path_, "r") if handle_ then while true do -- 读取第一行(带[]的配置项行,直接忽略) local first_line = handle_:read("*l") if not first_line then break end -- 文件读取完毕,退出循环 -- 读取第二行(包含可读名称的行) local second_line = handle_:read("*l") if not second_line then break end -- 先去除行尾空白,避免匹配失败 local trimmed_line = second_line:gsub("%s+$", "") local human_Name = trimmed_line:match("|(.+)") if human_Name then print(human_Name) end end handle_:close() end
额外容错处理
如果仍出现匹配失败,可尝试同时去除行首行尾的所有空白字符:
local trimmed_line = line:gsub("^%s+", ""):gsub("%s+$", "") -- 去掉行首行尾空白 local human_Name = trimmed_line:match("|(.+)")
内容的提问来源于stack exchange,提问作者Tormy Van Cool
相关产品推荐
相关产品推荐

