lua按照路径文件名排序和名字首字母区分

⌚Time: 2025-05-03 21:56:00

👨‍💻Author: Jack Ge

储存在appNameList里面的是文件路径,需要按照路径最后的文件名排序

--排序
table.sort(appNameList, function(a, b)
    -- 提取最后一级目录名(去掉末尾的 '/')
    local function getLastPart(p)
        p = p:gsub("/+$", "")  -- 移除末尾的 '/'
        return p:match("([^/]+)/?$") or p
    end
        
    local nameA = getLastPart(a)
    local nameB = getLastPart(b)
    return nameA < nameB  -- 按文件名升序排序(A-Z)
end)

上面的排序对于中文有效,会根据拼音顺序排序,而不区分大小写排序最后可以是return nameA:lower() < nameB:lower()

排序后对路径遍历,调用generateAppHref函数对每个路径处理,对名字进行遍历时,发现首字母与之前不同的就打印出来

比如对于名字

aaa
大龙虾
小香蕉
asdf
ccc
bbb
大苹果
小橘子

应该得到输出

--a--
aaa
asdf
--b--
bbb
--c--
ccc
--大--
大龙虾
大苹果
--小--
小橘子
小香蕉

ai给的代码是


local lastInitial = nil
for _, path in ipairs(appNameList) do
    local lastPath = path:gsub("/+$", "")
    local lastName = lastPath:match("([^/]+)/?$") or lastPath
    local currentInitial = lastName:sub(1, 1):upper()  -- 取首字母并大写
    -- 如果首字母变化,打印分隔行
    if currentInitial ~= lastInitial then
        html:write('<p>'..currentInitial..'</p>\n')
        lastInitial = currentInitial
    end
    --产生内容
    generateAppHref(html, path)
end

其中的

local currentInitial = lastName:sub(1, 1):upper()  -- 取首字母并大写

lastName:sub(1, 1):upper(),但是只能处理英文字母,在打印中文字符时是乱码

我改成lastName:sub(1, 2):upper()就可以处理中文情况,应该是因为中文占用了2个字节的编码。在gbk的编码情况下。

但是之后打印的中文是1个首字符,但是英文是2个首字符。所以我又判断中英文情况了,办法就是检查第一个字符是否是英文字母

if(currentInitial:sub(1, 1):match("[a-zA-Z]") ~= nil) then
    --是英文
else
    --是中文
end

所以代码就成了


--遍历生成内容
local lastInitial = nil
for _, path in ipairs(appNameList) do
    local lastPath = path:gsub("/+$", "")
    local lastName = lastPath:match("([^/]+)/?$") or lastPath
    -- 取首字母并大写(sub(1, 2)能提取到第一个中文字符,而sub(1,1)只能提取英文字符,提取中文字符会乱码)
    local currentInitial = lastName:sub(1, 2):upper()
    --检查lastInitial
    if lastInitial ~= nil then
            
        --区分中英文
        if(currentInitial:sub(1, 1):match("[a-zA-Z]") ~= nil) then
            --英文
            -- 如果首字母变化,打印分隔行
            if currentInitial:sub(1, 1) ~= lastInitial:sub(1, 1) then
                html:write('<p>'..currentInitial:sub(1, 1)..'</p>\n')
            end
        else
            --中文
            -- 如果首字母变化,打印分隔行
            if currentInitial ~= lastInitial then
                html:write('<p>'..currentInitial..'</p>\n')
            end
        end
    else

        --区分中英文
        if(currentInitial:sub(1, 1):match("[a-zA-Z]") ~= nil) then
            html:write('<p>'..currentInitial:sub(1, 1)..'</p>\n')
        else
            html:write('<p>'..currentInitial..'</p>\n')
        end
    end
    lastInitial = currentInitial
    --产生内容
    generateAppHref(html, path)
end



这样就能判断是中英文,分情况打印首字母显示了。

ai多次提醒我这种写法不完善,有缺点,让我改,但是它改的要用到什么库,很复杂,又用到lua5.3,utf8的库什么的,但是经典的lua版本是5.1,所以我没有听它的。

但是其之后让我显式检测 GBK 中文首字节

local function getFirstChar(str)
    if #str == 0 then return "" end
    local firstByte = str:byte(1)
    -- GBK 中文首字节范围:0x81-0xFE
    if firstByte >= 0x81 and firstByte <= 0xFE then
        return str:sub(1, 2):upper()  -- GBK 中文
    else
        return str:sub(1, 1):upper()   -- 英文
    end
end