string类库
这里描述的都是string模块提供的功能,在使用的时候具有两种形式。
print("hello":len())
-- 5
print(string.len("hello"))
-- 5
之后这里都采用string.len(s)
这种形式。
基础字符串功能
方法 | 描述 |
---|---|
string.len(s) | 获取字符串s的长度 |
string.upper(s) | 将字符串s转换为大写,遵循区域设置 |
string.lower(s) | 将字符串s转为小写,遵循区域设置 |
string.rep(s, n, sep) | 对s进行n次重复,如果有sep,则在每次重复之间添加sep |
string.sub(s, i, j) | 对字符串s进行截取,返回从第i 位置开始,到j 位置结束的子字符串 |
string.reverse(s) | 对字符串s进行反转 |
string.byte(s, i, j) | 返回字符串中位置i 的内部数值,当j 指定时,返回位置之间所有字符的内部数值 |
string.char(...) | 与byte相反,由数值转为字符 |
string.format(formatstring, ...) | 格式化字符串,%f浮点数,%d十进制,%x十六进制,%o八进制,%s字符串 |
- 字符串长度计算
local str = "hello lua!"
print(string.len(str))
-- 10
- 字符串大小写转换
字符串大小写转换方法lower
、upper
可以实现字符串转为小写或大写,不改变原始字符串,返回一个转换后的副本。这两个方法均遵循本地区域设置,如中文地区,其汉语拼音大小写将都按本地拼音规则,不改变。
local str = "hello LUA!中国拼音mǎ yü"
print(string.lower(str)) -- 注意ǎ,ü
-- hello lua!中国拼音mǎ yü
print(string.upper(str))
-- HELLO LUA!中国拼音Mǎ Yü
- 字符重复方法
rep
方法可以快速实现一个指定字符串重复指定次数的拼接,并返回拼接后的字符串。如果需要快速生成一些测试数据时,可以使用该函数。
local str = "hello lua."
print(string.rep(str, 3))
-- hello lua.hello lua.hello lua.
print(string.rep(str, 3, "你好"))
-- hello lua.你好hello lua.你好hello lua.
-- 如果有需要生成一个1G的文档,用于测试上传性能,可以使用rep
local data = string.rep("a", 1024*1024*1024)
- 字符串截取方法
sub
方法用于截取子字符串,i
值为开始截取的位置,子字符串包括该位置,从1
开始。j
表示截取的终止位置,包括该。i
、j
均支持取负值,表示从尾部开始计算,当都是正数或负数时满足i<=j
;这一点同redis的位置获取方式一致。正负取值可以混用,如获取一个字符的全部可以简化为sub(1, -1)。当j
超过总长度时,默认返回全部字符串。
该方法不会改变原有的字符串,只返回一个新创建的副本字符串。
local str = "hello lua."
print(string.sub(str, 1, 5))
-- hello
print(print(string.sub(str, -4, -1)))
-- lua.
print(string.sub(str, 1, -1))
-- hello lua.
- 字符串反转
local str = "hello lua."
print(string.reverse(str)) -- 实现字符串反转,返回一个副本,不改变原始字符串
-- .aul olleh
- 字符、内部数值相互转换方法
char
可以将内部数值(如ASCII)转为字符,byte
可以将字符串中指定位置的字符转为内部数值。两者相互转换。
byte(str, i, j)
接收一个字符串,两个位置,当两个位置都忽略时,默认转换第一个字符;i
为起始位置,从1
开始,当j
缺省时,只转换第i
个字符,并将转换结果返回;当j
传入时,转换从i
到j
中间的所有字符,包括起止位置。当j
超过总长度时,默认返回全部字符串。i,j
取值规则同sub方法一致,支持负数。
local str = "a dog."
print(string.byte(str))
-- 97
print(string.byte(str, 2)) -- 空格
-- 32
print(string.byte(str, 1, 3)) -- a空格d
-- 97 32 100
local t, j, k = string.byte(str, 1, 3)
print(t, j, k)
-- 97 32 100
print(string.byte(str, 1, -1)) -- 全部
-- 97 32 100 111 103 46
print(string.byte(str, 5, 10)) -- 最后两个字符
-- 103 46
char(...)
可以实现传入任意内部数值(ASCII)转为字符串,和byte方法刚好相反。该方法不能对超过2K
的字符串进行操作。
print(string.char(97, 98, 99))
-- abc
- 格式化字符串
format
方法用于格式化字符串,使用上同java的格式化方法基本上一致。
local f = "《%s》, reading process:%.2f%%, The page:%4d/%4d"
print(string.format(f, "hello lua", 50.126, 512, 1000))
-- 《hello lua》, reading process:50.13%, The page:0512/1000
支持的格式操作有
格式 | 描述 |
---|---|
%c | 接收数字,并转为ASCII对应字符 |
%d|%i | 接收并格式化整数,有符号,%02d-格式化2位,补足补0 |
%o | 八进制 |
%u | 格式化整数,无符号 |
%x|%X | 十六进制,小写|大写表示 |
%f | 浮点数,%.4f,其中4为有效数字 |
%q | 接受一个字符串并将其转化为可安全被Lua编译器读入的格式 |
%s | 字符串 |
%e|%E | 科学记数法标识,e小写,E大写 |
%g|%G | %G对应%E,格式化时为%e或%f中较短的一种 |
%% | 输出%,相当于转义 |
字符串查找
Lua的字符串查找被称为模式匹配,类似于正则,但不等于,会比正则的范围小。
方法 | 描述 |
---|---|
string.find(s, pattern, start) | 在字符串中搜索模式,start默认为1,从那个位置开始搜索,返回搜索到的位置起止位置,未找到返回nil |
string.match(s, pattern) | 在字符串中搜索模式,返回匹配的字符串 |
string.gsub(s, pattern, repl,n) | 替换方法,在字符串中搜索模式,匹配后使用repl进行替换 |
string.gmatch(s, pattern) | 查找模式,并返回函数,用于迭代所有匹配的字符串 |
- 模式
Lua中字符串的查找,主要是用模式进行匹配,同正则有关联,也有不同,通常情况下直接使用字符串字面值表示也能完成大部分查找需求,但总有需要更加有效的场景,如查找数字等。在实现Lua字符查找时,不能借助Java中的正则经验,需要从Lua支持的字符分类中去编写适配的模式,下表为Lua支持的字符分类。
最简单的模式就是字符串的字面值。
模式 | 描述 |
---|---|
%a | 字母 |
%c | 控制字符 |
%d | 数字 |
%l | 小写字母,支持本地化,如拼音 |
%p | 标点符号 |
%s | 空白字符 |
%u | 大写字母 |
%w | 字母和数字 |
%x | 十六进制数字 |
%z | 内部表示0的字符 |
如果将上述分类中的字母大写,如%W,表示对%w的补集,即既不是字母也不是数字,其他类似。
local str = "hello world34"
local nonChar = "%A" -- 该模式可以查找空格,3、4
local num = "%d" -- 可匹配3、4
local space = "%s" -- 可匹配空格
local str2 = "hello。."
local b = "%p" -- 可匹配标点符号. 无法匹配中文句号,中文占3个字符位置
(、)、[、]、.、+、-、*、%、?、$、^
这些字符为特殊字符,需要转义,使用%转义,如%( 匹配左括号
和正则一致,采用[]
用于描述字符集,如[ABC]
匹配大写字母A、B、C,[%w]
匹配字母和数字。集合支持范围,如[A-F]
表示只在A、F及之间的大写字母。在字符集前加上^
表示补集,如[^A-F]
表示A-F及之间大写字母外的其他任意字符。
local str = "A123acB34dC"
print(string.find(str, "[ABC]", 2))
-- 7 7
同正则一样,模式也可以使用修饰符来对集合等进行限制,其支持的装饰符如下
修饰符 | 描述 |
---|---|
+ | 重复一次及多次 |
? | 出现0次或1次 |
* | 重复0次或多次 |
- | 重复0次或多次 |
local str = "A123acB34dC"
print(string.find(str, "%d+"))
-- 2 4
以
$
字符来匹配结尾,如%d$
,只匹配结尾,如果结尾是数字,则返回位置,否则为nil(这里指find)
%b
也是模式中的一个特殊标识,用于成对匹配,方式为%b<x><y>
,成对的字符分别为x\y
。
local str = "tia,[hello world]."
print(string.find(str, "%b[]"))
-- 5 17
- find,查找字符串位置
find
方法用于查找模式,匹配到,返回第一个找到的起始位置和终止位置,未找到时,返回nil,如果出现第三个参数,表示从第几个字符位置开始查找。
local str = "hello lua"
print(string.find(str, "lua"))
-- 7 9
print(string.find(str, "l")) -- 第一个l位置为3
-- 3 3
print(string.find(str, "oa"))
-- nil
print(string.find(str, "%s")) -- 空格
-- 6 6
使用指定搜索位置参数,查找一个字符串中所有匹配的位置集合
-- 查找字符串中出现ll的所有位置
local str = "smell small well pull."
local pos = {}
local p = "ll"
local index = 1
while true do
local i, j = string.find(str, p, index)
if i == nil then
break
end
pos[#pos + 1] = {
start = i,
over = j
}
index = j + 1
end
for _, v in pairs(pos) do
print(v.start, v.over)
end
-- 4 5
-- 10 11
-- 15 16
-- 20 21
- match,查找字符串
match函数在一个字符串中查找模式,和find函数基本类似,返回的结果时匹配到的字符串。
local str = "hello lua.lua"
print(string.match(str, "lua"))
-- lua
由于模式就是字符串字母值,因此一旦匹配上,返回的就是模式本身。当使用字符分类时,则与次就有所不同。
-- 采用模式,查找连续数字的字符串
local str = "hello lua.lua,33 page,total 123"
print(string.match(str, "%d+"))
-- 33
- gsub,替换字符串
gsub方法,将使用模式在字符串中查找所有匹配的位置,使用替代字符串进行替换。返回替换后的字符串,第二个返回值为替换的次数。gsub还有一种重载形式,传入第四个参数,用于限制替换的次数。
-- 将所有字符l替换为a
local str = "hello lua."
print(string.gsub(str, "l", "a"))
-- heaao aua. 3
-- 只替换2次,最后一个l未被替换
print(string.gsub(str, "l", "a", 2))
-- heaao lua. 2
基于gsub的特性,可以使用gsub用于统计字符串中某些字符的个数。string.gsub(str, 'a', 'a')
,返回的第二个值即为字符串中a出现的次数。
- gmatch,查找模式并返回函数用于迭代遍历所有找到的字符
local str = "hello lua."
print(string.gmatch(str, "l"))
-- function: 00000000007f9580
使用该方法,查找一段文本中,所有的出现的数字集合。
local str = "在 2019 年已经逐渐成为共识,Redmi K30 第一个亮点就在于其采用了 6.67 英寸 120Hz 刷新率 LCD 屏幕"
local nums = {}
for num in string.gmatch(str, "%d+") do
nums[#nums + 1] = num
end
for _, v in pairs(nums) do
print(v)
end
-- 2019
-- 30
-- 6
-- 67
-- 120