PGRData/Script/matrix/xcommon/XString.lua

411 lines
11 KiB
Lua
Raw Normal View History

--==============================--
-- 字符串相关扩展方法
--==============================--
local tonumber = tonumber
local next = next
local pairs = pairs
local string = string
local table = table
local math = math
local stringLen = string.len
local stringByte = string.byte
local stringSub = string.sub
local stringGsub = string.gsub
local stringFind = string.find
local stringMatch = string.match
local tableInsert = table.insert
local mathFloor = math.floor
--==============================--
--desc: 通过utf8获取字符串长度
--@str: 字符串
--@return 字符串长度
--==============================--
function string.Utf8Len(str)
local len = stringLen(str)
local left = len
local cnt = 0
local arr = { 0, 192, 224, 240, 248, 252 }
while left ~= 0 do
local tmp = stringByte(str, -left)
local i = #arr
while arr[i] do
if tmp >= arr[i] then
left = left - i
break
end
i = i - 1
end
cnt = cnt + 1
end
return cnt
end
--==============================--
--desc: 通过utf8获取单个字符长度
--@str: 单个字符
--@return 字符串长度
--==============================--
function string.Utf8Size(char)
if not char then
return 0
elseif char >= 252 then
return 6
elseif char >= 248 then
return 5
elseif char >= 240 then
return 4
elseif char >= 225 then
return 3
elseif char >= 192 then
return 2
else
return 1
end
end
--==============================--
--desc: 按utf8长度截取字符串
--@str: 字符串
--@return 字符串
--==============================--
function string.Utf8Sub(str, startChar, numChars)
local startIndex = 1
while startChar > 1 do
local char = stringByte(str, startIndex)
startIndex = startIndex + string.Utf8Size(char)
startChar = startChar - 1
end
local currentIndex = startIndex
while numChars > 0 and currentIndex <= #str do
local char = stringByte(str, currentIndex)
currentIndex = currentIndex + string.Utf8Size(char)
numChars = numChars - 1
end
return str:sub(startIndex, currentIndex - 1)
end
--==============================--
--desc: 将字符串分割成char table
--@str: 字符串
--@return char table
--==============================--
function string.SplitWordsToCharTab(str)
local len = stringLen(str)
local left = len
local chartab = {}
local arr = { 0, 192, 224, 240, 248, 252 }
while left ~= 0 do
local tmp = stringByte(str, -left)
local i = #arr
local value = left
while arr[i] do
if tmp >= arr[i] then
left = left - i
break
end
i = i - 1
end
local char = stringSub(str, -value, -left - 1)
if stringSub(str, -left, -left + 1) == "\\n" then
left = left - 2
char = char .. "\n"
end
tableInsert(chartab, char)
end
return chartab
end
--==============================--
--desc: 把有富文本格式的字符串变成char table
--@str: 富文本字符串
--@return char table
--==============================--
function string.CharsConvertToCharTab(str)
--str = "我只是用来{<color=#00ffffff><size=40>测一测</size></color>}别xiabibi{<size=25><color=#ff0000ff>红色试一试</color></size>}试玩啦"--
local leftindexs = {}
local rightindexs = {}
local startpos = 1
while true do
local pos = stringFind(str, "{", startpos)
if not pos then
break
end
tableInsert(leftindexs, pos)
pos = stringFind(str, "}", pos + 1)
if not pos then
break
end
tableInsert(rightindexs, pos)
startpos = pos + 1
end
local words = {}
if #leftindexs > 0 then
startpos = 1
for i = 1, #leftindexs do
tableInsert(words, stringSub(str, startpos, leftindexs[i] - 1))
tableInsert(words, stringSub(str, leftindexs[i] + 1, rightindexs[i] - 1))
startpos = rightindexs[i] + 1
end
if rightindexs[#rightindexs] ~= stringLen(str) then
tableInsert(words, stringSub(str, startpos))
end
else
tableInsert(words, str)
end
local result = {}
for i = 1, #words do
local tab
local IsRichText
local format
if stringSub(words[i], 1, 1) == "<" then
IsRichText = true
local pa = stringMatch(words[i], "%b></")
pa = stringMatch(pa, ">(.*)<")
format = stringGsub(words[i], "%b></", ">#$#</", 1)
tab = string.SplitWordsToCharTab(pa)
else
IsRichText = false
format = ""
tab = string.SplitWordsToCharTab(words[i])
end
for j = 1, #tab do
if IsRichText then
local char = stringGsub(format, "#$#", tab[j])
tableInsert(result, char)
else
tableInsert(result, tab[j])
end
end
end
return result
end
--==============================--
--desc: 检查字符串的开头是否与指定字符串匹配
--@str: 需要检查的字符串
--@value: 指定的字符串
--@return true匹配false不匹配
--==============================--
function string.StartsWith(str, value)
return stringSub(str, 1, stringLen(value)) == value
end
--==============================--
--desc: 检查字符串的结尾是否与指定字符串匹配
--@str: 需要检查的字符串
--@value: 指定的字符串
--@return true匹配false不匹配
--==============================--
function string.EndsWith(str, value)
return value == "" or stringSub(str, -stringLen(value)) == value
end
--==============================--
--desc: 字符串分割
--@str: 原字符串
--@separator: 分割符
--@return 字符串数组
--==============================--
function string.Split(str, separator)
if str == nil or str == "" then
return {}
end
if not separator then
separator = "|"
end
local result = {}
local startPos = 1
while true do
local endPos = str:find(separator, startPos)
if endPos == nil then
break
end
local elem = str:sub(startPos, endPos - 1)
tableInsert(result, elem)
startPos = endPos + #separator
end
tableInsert(result, str:sub(startPos))
return result
end
--==============================--
--desc: 将字符串分割成int数组
--@str: 原字符串
--@separator: 分割符
--@return int数组
--==============================--
function string.ToIntArray(str, separator)
local strs = string.Split(str, separator)
local array = {}
if next(strs) then
for _, v in pairs(strs) do
tableInsert(array, mathFloor(tonumber(v)))
end
end
return array
end
--==============================--
--desc: 从一个字符串中查找另一个字符串的第一次匹配的索引
--@str: 原字符串
--@separator: 需要匹配的字符串
--@return 索引号
--==============================--
function string.IndexOf(str, separator)
if not str or str == "" or not separator or separator == "" then
return -1
end
for i = 1, #str do
local success = true
for s = 1, #separator do
local strChar = stringByte(str, i + s - 1)
local sepChar = stringByte(separator, s)
if strChar ~= sepChar then
success = false
break
end
end
if success then
return i
end
end
return -1
end
--==============================--
--desc: 从一个字符串中查找另一个字符串的最后一次匹配的索引
--@str: 原字符串
--@separator: 需要匹配的字符串
--@return 索引号
--==============================--
function string.LastIndexOf(str, separator)
if not str or str == "" or not separator or separator == "" then
return -1
end
local strLen = #str
local sepLen = #separator
for i = 0, strLen - 1 do
local success = true
for s = 0, sepLen - 1 do
local strChar = stringByte(str, strLen - i - s)
local sepChar = stringByte(separator, sepLen - s)
if strChar ~= sepChar then
success = false
break
end
end
if success then
return strLen - i - sepLen + 1
end
end
return -1
end
--==============================--
--desc: 判断字符串是否为nil或者为空
--@str: 字符串对象
--@return 如果为nil或者为空返回true否则返回fale
--==============================--
function string.IsNilOrEmpty(str)
return str == nil or #str == 0
end
--==============================--
--desc: 过滤utf文本特殊屏蔽字干扰字符
--@str: 字符串对象
--@return 过滤后文本
--==============================--
local FilterSymbols = [[·~@#¥%……&*-=——+【】{}、|;‘’:“”,。、《》?[]{}""'';:./?,<>\|-_=+*()!@#$%^&*~` ]]
local FilterSymbolsTable = FilterSymbols:SplitWordsToCharTab()
function string.FilterWords(str)
local result = ""
for i = 1, string.Utf8Len(str) do
local nowStr = string.Utf8Sub(str, i, 1)
local isValid = true
for _, v in pairs(FilterSymbolsTable) do
if nowStr == v then
isValid = false
break
end
end
if isValid then
result = result .. nowStr
end
end
return result
end
--==============================--
--desc: 字符串每隔X个字符插入 需要的字符串
--@str: 字符串对象
--@interval: 间隔多少个字符
--@insertStr: 插入的字符串
--@return 过滤后文本
--==============================--
function string.InsertStr(str, interval, insertStr)
local index = 1
local worldCount = 0
local result = ""
while true do
local world = stringSub(str, index, index)
local byte = stringByte(world)
if byte > 128 then
world = stringSub(str, index, index + 2)
index = index + 3
else
index = index + 1
end
result = result .. world
worldCount = worldCount + 1
if worldCount >= interval then
result = result .. insertStr
worldCount = 0
end
if index > #str then
break
end
end
return result
end
--判断字符串是否为合法IP"[0-255].[0-255].[0-255].[0-255]"
function string.IsIp(ip)
if string.IsNilOrEmpty(ip) then return false end
local valueSet = table.pack(string.find(ip, "(%d+)%.(%d+)%.(%d+)%.(%d+)"))
local pureIpStr = table.concat(valueSet, '.', 3, 6)
if not valueSet[1] then return false end
local ipNum
for i = 3, 6 do
ipNum = tonumber(valueSet[i])
if not ipNum or ipNum < 0 or ipNum > 255 then
return false
end
end
return true, pureIpStr
end