lua中的字符串
在lua中字符串的类型是 string
,通常字符串的拼接是通过..
例如
local str = "te"
local str2 = "st"
local str3 = str .. str2
print(str3) --输出 test
print(type(str3)) --输出 string
但是其实很少有人关注,字符串其实是一个表,可以 getmetatable
获取到相应的原表
local str = ""
local mt = getmetatable(str);
而且有意思的是普通字符串相应的原表的__index
居然是 string
库,这意味则,其实普通字符串可以直接调用string
库接口,而且扩展了string
库,那么普通字符串也具有相关功能(原表原理)。 基于此原理,我们可以对字符串进行扩展实现一些骚操作,例如下面的代码
local tmp = "test"
local str = "stringtest";
local mt = getmetatable(tmp);
print(mt.__index)
print(string)
if mt.__index == string then
print("普通字符串的原表元方法__index是string")
end
print(str[1]) --输出是nil
--扩展元方法__index
mt.__index = function(str, i)
if (type(i) == 'number') then
return string.sub(str, i, i)
end
return string[i]
end
--再次验证str[1]
print(str[1]) --输出是 s
---实现函数调用式字符串截取
-- local b = str(2,5) --此时运行会报错 attempt to call local 'str' (a string value)
--扩展元方法__call
mt.__call = function(str, i, j)
if (type(i) == 'number' and type(j) == 'number') then
return string.sub(str, i, j)
elseif (type(i) == 'number' and type(j) == 'string') then
return table.concat{string.sub(str, 1, i - 1), j, string.sub(str, i + 1)}
elseif (type(i) == 'number' and type(j) == 'nil') then
return string.byte(str, i)
end
return string[i]
end
local b = str(2,5);
print(b) -- 输出 trin
---实现字符串加法
-- local b = tmp + str --此时运行会报错 attempt to perform arithmetic on local 'tmp' (a string value)
--扩展元方法__add
mt.__add = function(str1, str2)
return table.concat({str1,str2})
end
local b = tmp + str
print(b) -- 输出 teststringtest
---实现字符串减法
-- local b = str - tmp --此时运行会报错 attempt to perform arithmetic on local 'str' (a string value)
--封装一下简单的字符串移除接口
--[[--
移除str中符合pattern模式的子串,最多不超过limit个
@tparam string str 目标字符串
@tparam string pattern 匹配模式
@tparam number limit 移除上限
@return string 移除后的字符串
@usage
string.remove("213123xi","3",1) -- "21123xi"
]]
function string.remove(str, pattern, limit)
if (pattern == '' or pattern == nil) then
return str
end
if (limit == '' or limit == nil) then
str = string.gsub(str, pattern, '')
else
str = string.gsub(str, pattern, '', limit)
end
return str
end
--扩展元方法__sub
mt.__sub = function(str1, str2)
return str1:remove(str2) -- 这里的调用方式等价于 string.remove(str1,str2)
end
local b = str - tmp
print(b) -- 输出 string
--实现字符串分割
--[[--
按照分隔符delimiter分割字符串成table
@tparam string str 目标字符串
@tparam string delimiter 分隔符
@return table 被分割的表
@usage
local a = string.split("axbxc","x")
a = {a,b,c}
]]
function string.split(str, delimiter)
if (delimiter == '') then return false end
local pos, arr = 0, {}
-- for each divider found
for st, sp in function() return string.find(str, delimiter, pos, true) end do
table.insert(arr, string.sub(str, pos, st - 1))
pos = sp + 1
end
table.insert(arr, string.sub(str, pos))
return arr
end
local path = "c:\\user\\tmp\\lua"
local list = path:split("\\") --此时list 等于 {c:,user,tmp,lua}
for i,v in ipairs(list) do
print(i,v)
end
--以下是测试string自带接口
--字符串全部转为大写字母
local b = str:upper()
print(b) -- 输出 STRINGTEST
--找到索引
local i = str:find("test")
print(i)-- 输出 7
--在字符串中替换
local b = str:gsub("test","lua")
print(b) -- 输出 stringlua