最近在项目中有一个需求,对邮件中的指定内容做解析,比如邮件中含有城市的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))
下面是输出:
在广州有龟苓膏卖