Lua编写简单的内容解析器

Posted 小龙的编程笔记本

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Lua编写简单的内容解析器相关的知识,希望对你有一定的参考价值。

    最近在项目中有一个需求,对邮件中的指定内容做解析,比如邮件中含有城市的id,或者是包含某商品id等等,需要将id提取出来自己解析,并将结果拼接好显示出来,所以就有了这个。我们这里采取的是用特殊字符来把对应内容包裹起来,在拿到数据后再根据规则解析出来。比如我们用 $id$来表示城市id。在id为2001的城市用id为3000的商品卖,得到的数据可能是在$2001$有@3000@卖

    由于在字符串中可能会包含中文,所以遍历的时候不能直接一个一个位置读,我们区分读到的字符是普通字符还是中文字,可以用string.byte来获取字节大小,如果得到的数值大于128,则是中文字,我们需要一次性读三位才能把中文字正确显示。

    在对内容里的特殊内容查找时,我定义了一个specialSign的表,当找到一个特殊字符时,则继续遍历,直到找到下一个同样的字符,并保存中间的所有信息,找完后根据这个特殊符号对中间信息单独解析。

    这样之所以正确,有两个前提:1、特殊的字符不能在正常内容中出现,即普通情况不应该出现这个符号。2、特殊字符不能嵌套。这个应该是很好满足的,这种解析通常不会嵌套出现。如果真的可以嵌套出现,那可能得使用递归去反复查找了。

    下面是代码:

function GetWard(info,i)
    local ward = string.sub(info,i,i)
    local byteWard = string.byte(ward)    if byteWard > 128 then
        ward = string.sub(info,i,i+2)
        i = i + 3
    else
        i = i + 1
    end    return ward,i
end

function AnalysisWard(info,sign)    if sign == '$' then
        info = tonumber(info)        return "广州" --这里修改为自己的查询方式,一般是通过id从表里查询对应信息
    elseif sign == '@' then        return "龟苓膏"
        --可添加更多的解析
    end    return " "end

function GetTrulyInfo(info)
    local specialSign =
    {        '$',        '&',        '#',        '@'
    }
    local resInfo = ""
    local i = 1
    local ward = ""
    while true do
        ward,i = GetWard(info,i)
        local isSpecialWard = false        for key,value in pairs(specialSign)do            if value == ward then --找到了一个标志,则往后找下一个标志
                isSpecialWard = true
                local tempInfo = ""
                local nextWard = ""
                while true do
                    nextWard,i = GetWard(info,i)                    if nextWard == value then                        break
                    end
                    tempInfo = tempInfo .. nextWard
                end                if tempInfo ~= "" then
                    tempInfo = AnalysisWard(tempInfo,value)
                    resInfo = resInfo .. tempInfo
                end                break
            end
        end        if not isSpecialWard then
            resInfo = resInfo .. ward
        end        if i > #info then
            break
        end
    end    return resInfo
end

local info = "在$12$有@3000@卖"print(GetTrulyInfo(info))

下面是输出:

在广州有龟苓膏卖