local ipairs = ipairs local pairs = pairs local table_insert = table.insert local table_concat = table.concat local table_remove = table.remove local string_format = string.format local type = type local tonumber = tonumber local next = next local strh = require "strh" function string.setv(str, k, v, delimiter) delimiter = delimiter or " " -- 若存在则替换,若无则append return strh.modify(str, {[tonumber(k)]=tonumber(v)}, false, delimiter) end function string.msetv(str, vs, delimiter) delimiter = delimiter or " " if not next(vs) then return str end return strh.modify(str, vs, false, delimiter) end function string.incrv(str, k, delta, delimiter) delimiter = delimiter or " " return strh.modify(str, {[tonumber(k)]=tonumber(delta)}, true, delimiter) end function string.mincrv(str, ds, delimiter) delimiter = delimiter or " " if not next(ds) then return str end return strh.modify(str, ds, true, delimiter) end function string.delk(str, k, delimiter) delimiter = delimiter or " " return strh.modify(str, {[tonumber(k)]=""}, false, delimiter) end function string.mdelk(str, ks, delimiter) delimiter = delimiter or " " local mod = {} for _, k in ipairs(ks) do mod[k] = "" end return strh.modify(str, mod, false, delimiter) end function string.getv(str, k, default, delimiter) default = default or -1 delimiter = delimiter or " " return strh.getv(str, k, default, delimiter) end function string.toArray(str, toNum, delimiter) delimiter = delimiter or " " return strh.toarray(str, tobool(toNum), delimiter) end function string.value(str, index, default, notNum, delimiter) delimiter = delimiter or " " local bfind, value = strh.value(str, index, delimiter) if not notNum then value = tonumber(value) end return bfind and value or (default or value) end function string.setv_dk(str, k1, k2, v, delimiter) delimiter = delimiter or " " local mod = {[k1]={[k2]=v}} return strh.moddk(str, mod, false, delimiter) end -- {{k1,k2,v}} function string.msetv_dk(str, vs, delimiter) delimiter = delimiter or " " if not next(vs) then return str end local mod = {} for _, t in ipairs(vs) do local k1 = tonumber(t[1]) local k2 = tonumber(t[2]) local v = tonumber(t[3]) if mod[k1] then mod[k1][k2] = v else mod[k1] = {[k2] = v} end end return strh.moddk(str, mod, false, delimiter) end function string.incrv_dk(str, k1, k2, delta, delimiter) delimiter = delimiter or " " local mod = {[tonumber(k1)]={[tonumber(k2)]=tonumber(delta)}} return strh.moddk(str, mod, true, delimiter) end function string.mincrv_dk(str, ds, delimiter) delimiter = delimiter or " " if not next(ds) then return str end local mod = {} for _, t in ipairs(ds) do local k1 = tonumber(t[1]) local k2 = tonumber(t[2]) local delta = tonumber(t[3]) if mod[k1] then mod[k1][k2] = delta else mod[k1] = {[k2] = delta} end end return strh.moddk(str, mod, true, delimiter) end function string.delk_dk(str, k1, k2, delimiter) delimiter = delimiter or " " local mod = {[tonumber(k1)]={[tonumber(k2)]=""}} return strh.moddk(str, mod, false, delimiter) end function string.mdelk_dk(str, ks, delimiter) delimiter = delimiter or " " local mod = {} for _, t in ipairs(ks) do local k1 = tonumber(t[1]) local k2 = tonumber(t[2]) if mod[k1] then mod[k1][k2] = "" else mod[k1] = {[k2] = ""} end end return strh.moddk(str, mod, false, delimiter) end function string.getv_dk(str, k1, k2, default, delimiter) default = default or -1 delimiter = delimiter or " " return strh.getvdk(str, k1, k2, default, delimiter) end function string.toNumMap(str, delimiter) delimiter = delimiter or " " return strh.tonummap(str, delimiter) end --[[ from: 1=2=3 to: {"1","2","3"} ]] function string.split2(str, pattern) pattern = pattern or "[%d.=]+" local tb = {} for v in str:gmatch(pattern) do table_insert(tb, v) end return tb end --[[ from: 1=2 3=4 to: {["1"]="2",["3"]="4"} ]] function string.tomap(str) local tb = {} for k, v in str:gmatch("([%d.]+)=([%d.]+)") do tb[k] = v end return tb end --[[ from: 1=2 3=4 5=6.1 to: {{1,2},{3,4},{5,6.1}} ]] function string.toAttrMap(str, pattern) pattern = pattern or "([%d.]+)=([%d.]+)" local tb = {} for k, v in str:gmatch(pattern) do tb[#tb+1] = {tonum(k), tonum(v)} end return tb end --[[ from: "1=2=3 4=5=6" to: {{"1", "2", "3"}, {"4", "5", "6"}} ]] function string.toTableArray(str, toNum, delimiter, pattern) pattern = pattern or "[%d.=]+" delimiter = delimiter or "=" local tb = {} for v in str:gmatch(pattern) do tb[#tb+1] = v:toArray(toNum, delimiter) end return tb end function string.toTableArraySec(str, delimiter) delimiter = delimiter or " " local array = {} local tempArray = string.split(string.trim(str), delimiter) for _, value in ipairs(tempArray) do local trimValue = string.trim(value) if trimValue ~= "" then value = string.split(trimValue, "=") table_insert(array, value) end end return array end --[[ from: "x1=x2=x3=x4 y1=y2=y3=y4" to: {[x1]={x2,x3,x4},[y1]={y2,y3,y4}} ]] function string.toAttArray(str) local tb = {} for v1, vt in str:gmatch("([%d.]+)=([%d.=]+)") do tb[tonum(v1)] = vt:toArray(true) end return tb end --[[ x=x...=x x=x...=x 最后一个x为权值 返回权值之外的值 ]] function string.randWeight(str, bMulti) if not str or str == "" then return nil end local tab, sum = {}, 0 for index, vstr in ipairs(str:toArray()) do local tmp = vstr:toArray(true, "=") sum = sum + tmp[#tmp] tab[index] = tmp end local weight = math.randomFloat(0, sum) for _, v in ipairs(tab) do local val = v[#v] if val < weight then weight = weight - val else if bMulti then table_remove(v) return v else return v[1] end end end end function string.randLine(str) local num = str:nums("%d+") local index = math.random(num) return tonumber(str:value(index)) end --[[ 结构类似如: v1;v2;v3; ]] function string.sismember(str, value, delimiter) delimiter = delimiter or ";" for _, v in ipairs(str:toArray(true, delimiter)) do if v == val then return true end end end function string.sadd(str, value, delimiter) delimiter = delimiter or ";" if str:sismember(value) then return str end return table_concat({str, value, delimiter}) end function string.srem(str, value, delimiter) delimiter = delimiter or ";" local form = table_concat({"([^", delimiter, "]+)", delimiter}) local str = str:gsub(form, {[tostring(value)]=""}) return str end --[[ from: 1 2 3 4 5 to: 数字的个数 这里是5 ]] function string.nums(str, format) format = format or "%d+" local count = 0 for _ in str:gmatch(format) do count = count + 1 end return count end -- getbit setbit 支持负索引 function string.getbit(str, pos) local len = #str if pos > len or len+pos < 0 then return 48 end if pos < 0 and len+pos >= 0 then pos = len+pos+1 end return str:byte(pos) end function string.bitcnt(str) local cnt = 0 for i=1, #str do cnt = cnt + str:byte(i) - 48 end return cnt end function string.setbit(str, pos, yes) yes = yes or "1" local len = #str if pos < 0 then if len+pos < 0 then return str end pos = len+pos+1 end if len < pos then return str .. string.rep("0", pos-len-1) .. yes else return str:sub(1, pos-1) .. yes .. str:sub(pos+1, -1) end end