StringUtil.lua 7.15 KB
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