2025-06-04 05:02:57 +08:00

274 lines
7.1 KiB
Plaintext

StringUtil = {};
function StringUtil.utf8_tail(n, k)
local u, r=''
for i=1,k do
n,r = math.floor(n/0x40), n%0x40
u = string.char(r+0x80) .. u
end
return u, n
end
function StringUtil.to_utf8(a)
local n, r, u = tonumber(a)
if n<0x80 then -- 1 byte
return string.char(n)
elseif n<0x800 then -- 2 byte
u, n = StringUtil.utf8_tail(n, 1)
return string.char(n+0xc0) .. u
elseif n<0x10000 then -- 3 byte
u, n = StringUtil.utf8_tail(n, 2)
return string.char(n+0xe0) .. u
elseif n<0x200000 then -- 4 byte
u, n = StringUtil.utf8_tail(n, 3)
return string.char(n+0xf0) .. u
elseif n<0x4000000 then -- 5 byte
u, n = StringUtil.utf8_tail(n, 4)
return string.char(n+0xf8) .. u
else -- 6 byte
u, n = StringUtil.utf8_tail(n, 5)
return string.char(n+0xfc) .. u
end
end
function StringUtil.sto_utf8(s)
return string.gsub(s, '&#(%d+);', StringUtil.to_utf8)
end
--startIndex can't bigger endIndex
--endIndex can be nil
local tab = {}
function StringUtil.getTextByIndex( str,startIndex,endIndex)
if(endIndex and endIndex < startIndex)then
printRed("error!startIndex can't bigger endIndex")
return ""
end
TableUtility.ArrayClear(tab);
for uchar in string.gmatch(str, "[%z\1-\127\194-\244][\128-\191]*") do
tab[#tab+1] = uchar
end
if(endIndex and endIndex > #tab or not endIndex)then
endIndex = #tab
end
return table.concat(tab, "", startIndex, endIndex)
end
function StringUtil.getTextLen( str)
-- body
local lenInByte = #str
local len = 0
local i = 1
local curByte
local byteCount = 1
while (i <= lenInByte)
do
curByte = string.byte(str, i)
if curByte > 0 and curByte <= 127 then
byteCount = 1
elseif curByte >= 192 and curByte < 223 then
byteCount = 2
elseif curByte >= 224 and curByte < 239 then
byteCount = 3
elseif curByte >= 240 and curByte <= 247 then
byteCount = 4
end
i = i + byteCount
len = len + 1
end
return len
end
function StringUtil.StringToCharArray( str)
-- body
local result = 0
local _, count = string.gsub(str, "[^\128-\193]", "")
local tab = {}
for uchar in string.gmatch(str, "[%z\1-\127\194-\244][\128-\191]*") do
tab[#tab+1] = uchar
end
return tab
end
function StringUtil.SubString( str,startIndex,length)
-- local result = 0
-- local _, count = string.gsub(str, "[^\128-\193]", "")
-- local tab = {}
-- for uchar in string.gmatch(str, "[%z\1-\127\194-\244][\128-\191]*") do
-- tab[#tab+1] = uchar
-- end
-- local max = math.min(#tab,startIndex + length-1)
-- local str = ""
-- for i = startIndex,max do
-- str = str..tab[i]
-- end
local maxIndex = math.max(StringUtil.ChLength(str), startIndex + length-1);
return StringUtil.Sub(str,startIndex,maxIndex)
end
function StringUtil.Sub(str, startIndex, endIndex)
local dropping = string.byte(str, endIndex+1)
if not dropping then return str end
if dropping >= 128 and dropping < 192 then
return StringUtil.Sub(str, startIndex, endIndex-1)
end
return string.sub(str, startIndex, endIndex);
end
-- 中文字串的長度
function StringUtil.ChLength(str)
return #(string.gsub(str, '[\128-\255][\128-\255]',' '))
end
function StringUtil.AnalyzeDialogOptionConfig(str)
local optionformat = "(%{([^%{%}]+)%,(%d+)%})";
local result = {};
for _,text,id in string.gmatch(str, optionformat) do
local optionConfig = {};
optionConfig.id = tonumber(id);
optionConfig.text = text;
table.insert(result, optionConfig);
end
if(#result==0)then
local optionConfig = {};
optionConfig.text = str;
optionConfig.id = 0;
table.insert(result, optionConfig);
end
return result;
end
function StringUtil.Split(str, delimiter)
if str==nil or str=='' or delimiter==nil then
return nil
end
local result = {}
for match in (str..delimiter):gmatch("(.-)"..delimiter) do
table.insert(result, match)
end
return result
end
function StringUtil.Json2Lua( str )
-- body
local luaString = LuaUtils.JsonToLua(str)
if nil ~= luaString then
luaString = "return "..luaString
local luaFunc = loadstring(luaString)
if nil ~= luaFunc then
local luaObject = luaFunc()
return luaObject
end
else
print("luaString is nil")
end
end
function StringUtil.Chsize(char)
if not char then
print("not char")
return 0
elseif char > 240 then
return 4
elseif char > 225 then
return 3
elseif char > 192 then
return 2
else
return 1
end
end
-- 計算utf8字串字元數, 各種字元都按一個字元計算
-- 例如Utf8len("1你好") => 3
function StringUtil.Utf8len(str)
local len = 0
local currentIndex = 1
while currentIndex <= #str do
local char = string.byte(str, currentIndex)
currentIndex = currentIndex + StringUtil.Chsize(char)
len = len +1
end
return len
end
function StringUtil.Replace(str,searchStr,replaceStr)
local replaceStr = string.gsub(replaceStr,"%%","%%%%")
return string.gsub(str,searchStr,replaceStr)
end
function StringUtil.NumThousandFormat(num, deperator)
if deperator == nil then
deperator = ","
end
deperator = deperator or ","
local result = "";
num = math.floor(num);
local str = tostring( math.abs(num) );
local slength = string.len(str);
for i=1, slength do
result = string.char(string.byte(str, slength + 1 - i))..result;
if( i % 3 == 0 and i < slength)then
result = deperator..result;
end
end
return num < 0 and "-"..result or result
end
local RomansMap = {
{1000, "M"},
{900, "CM"},
{500, "D"},
{400, "CD"},
{100, "C"},
{90, "XC"},
{50, "L"},
{40, "XL"},
{10, "X"},
{9, "IX"},
{5, "V"},
{4, "IV"},
{1, "I"}
}
function StringUtil.IntToRoman(num)
local k = num;
local roman, val, let = "";
for _, v in ipairs(RomansMap) do
val, let = v[1], v[2];
while k >= val do
k = k - val;
roman = roman .. let;
end
end
return roman;
end
function StringUtil.FormatTime2TimeStamp( formatTime )
local t = {};
local ifs = string.split(formatTime , " ");
local d1 = string.split(ifs[1], "-");
t.year, t.month, t.day = tonumber(d1[1]), tonumber(d1[2]), tonumber(d1[3]);
local d2 = string.split(ifs[2], ":");
t.hour, t.min, t.sec = tonumber(d2[1]), tonumber(d2[2]), tonumber(d2[3]);
return os.time(t);
end
function StringUtil.IsEmpty( content )
-- body
if(not content or content == "")then
return true
end
end
function StringUtil.LastIndexOf( content , findStr )
local found = content:reverse():find(findStr:reverse(), nil, true)
if found then
return content:len() - findStr:len() - found + 2
else
return found
end
end