You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

问题分析与解决方案

你的代码存在两个核心问题:

  1. 读取逻辑冲突:handle_:lines()已经在逐行遍历文件,循环内部又调用handle_:read("*l"),这种混合读取方式容易导致行顺序错位或读取异常;
  2. 匹配容错性不足:|(.+)$要求|后内容直达行尾,但如果行尾有隐藏空白字符(如换行符、空格),会导致匹配失败。

下面是两种可靠的解决代码:

方案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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 14:05:40