常用方法
- 与 ASCII码表相关的方法:
byte()
&char()
-- string.byte(s, [, i [, j]])
-- 返回索引从 i ~ j对应字符的 ASCII码 (注意 Lua中所有的索引都是从 1开始的)
print(string.byte('abc', 1, 3)) -- 97 98 99
-- 缺少第二个和第三个参数, 此时这两个参数的值默认都是 1
print(string.byte('abc')) -- 97
-- 缺少第三个参数, 此时第三个参数的默认值和第二个参数相同
print(string.byte('abc', 2)) -- 98
-- string.char()
-- 返回参数数字在 ASCII码表中对应的字符, 若有多个参数, 返回对应的字符连接起来的字符串
-- 使用可变参数, 接收 [0, 255]范围内的若干个整数,
-- 当不传参数时, 默认为一个 0, 返回一个空字符串
print(string.char()) --
print(string.char() == '' and type(string.char()) == 'string') -- true
print(string.char(65)) -- A
print(string.char(97, 98, 99)) -- abc
实用方法 upper()
& lower()
& len()
& #操作符
& rep()
& reverse()
& sub()
-- 大小写转换
print(string.upper('abc')) -- ABC
print(string.lower('ABc')) -- abc
-- 获取字符串长度
-- 不推荐使用 len函数, 在获取字符串长度是应当总是使用 #运算符
-- 这是因为 #运算符的效率更高:
-- string.len()需要先查找 string, 再找其下的 len,再传参再调用,至少需要 4条 lua vm bytecode;
-- 而 #直接被翻译为LEN指令,一条指令就可以算出来
print(string.len('abcde')) -- 5
print(#'abcde') -- 5
s = 'hello lua'
print(s:len()) -- 9
-- 关于 ' ' 字符串的说明
-- 在 C语言中: 是转义字符, 代表空字符串, 对应的 ASCII码为 0, 通常用来作为字符串的结束标志
-- 在 lua中:
-- 这里不是很明白 , 0, 00有什么区别
print(' ', #' ') -- 1
print(' 0', #' 0') -- 1
print(' 00', #' 00') -- 1
print(' 000', #' 000') -- 0 2
print(' ', #' ') -- 2
-- 获取某个字符串的多次重复
print(string.rep('*', 30)) -- ******************************
-- 字符串反转
print(string.reverse('hello lua')) -- aul olleh
-- 字符串截取
print(string.sub('hello lua', 3, 5)) -- llo
- 格式化字符串方法
format()
-- 字符串格式化
-- string.format(formatstring, ...)
-- 返回格式化后的字符串. 第一个参数是字符串格式, 后面是可变参数, 用于填充第一个参数中的格式控制符
-- 保留 4位小数
print(string.format('%.4f', 3.141592653)) -- 3.1416
-- 十进制数 15转换成不同进制数
print(string.format('%d %x %o', 15, 15, 15)) -- 15 f 17
-- 格式化一个日期
print(string.format('%s %04d-%02d-%02d', 'today is:', 2018, 5, 6)) -- today is: 2018-05-06
-- 格式控制符
-- 格式控制符以 %开头, 常用的有以下几种:
-- %s 接收一个字符串, 并按照给定的参数格式化该字符串
-- %d 接收一个数字, 并将其转化为有符号的整数格式
-- %f 接收一个数字, 并将其转化为浮点数, 默认保留 6位小数, 不足的位数用 0填充
-- %x 接收一个数字, 并将其转化为小写的十六进制数字
-- %X 接收一个数字, 并将其转化为大写的十六进制数字
print(string.format('%s %d %f %x %X', 'hello', -200, 35, 15, 31)) -- hello -200 35.000000 f 1F
-- %d, %x, %X的特殊用法
-- %08x 中间的第二个数字代表格式化成多少位, 第一个数字代表位数不足时的填充位, 通常以 0填充
print(string.format('%04d 0x%08x 0x%04X', 15, 255, 31)) -- 0015 0x000000ff 0x001F
-- %f的特殊用法
-- %0.3f 中间小数点右边的数字代表小数点后面保留多少位, 小数点前面的数字代表位数不足时的填充位, 通常以 0填充
print(string.format('%0.3f', 12)) -- 12.000
-- 用法归纳
-- %c 接收一个数字, 并将其转为 ASCII码表中对应的字符
-- %d (%i) 接收一个数字, 并将其转为 有符号的整数格式 (%d 和 %i的显示效果一样, 区别何在 ?)
-- %o 接收一个数字, 并将其转为 八进制数
-- %u 接收一个数字, 并将其转为 无符号的整数
-- %x 接收一个数字, 并将其转为 十六进制格式(小写字母)
-- %X 接收一个数字, 并将其转为 十六进制格式(大写字母)
-- %e 接收一个数字, 并将其转为 科学计数法格式 (e)
-- %E 接收一个数字, 并将其转为 科学计数法格式 (E)
-- %g (%G) 接收一个数字, 并将其转化为 %e(%E,对应 %G)及 %f中较短的一种格式
-- %q 接收一个字符串, 并将其转化为可安全被 Lua编译器读入的格式
-- %s 接收一个字符串, 并按照给定的参数格式化该字符串
print(string.format('%c %d %i 0%o %u', 65, -121, -15, 9, -2)) -- A -121 -15 011 18446744073709551614
print(string.format('0x%x 0x%X %e %E', 65, 66, 100, 1000)) -- 0x41 0x42 1.000000e+002 1.000000E+003
print(string.format('%g %G %q %s', 31, 10, 'hello', 'lua')) -- 31 10 "hello" lua
-- 为进一步细化格式, 可以在 %后添加参数, 参数将以如下的顺序读入
-- 1.符号: 一个 +表示其后的数字转义符将让整数显示正号, 默认情况下只有负数显示符号
-- 2.占位符: 一个 0, 在后面指定了字串宽度时占用, 不填时默认的占位符是空格
-- 3.对齐标识: 在指定了字串宽度时, 默认为右对齐, 增加 -号可以改为左对齐
-- 4.宽度数值
-- 5.小数位/字串裁剪: 在宽度数值后增加的小数部分 n, 若后接 f则设定该浮点数的小数位只保留 n位,
-- 若后接s, 则设定该字符串只显示前 n位
-- 在这些参数后面的则是上述所列的转义码类型 (s, c, f, ...)
-- 符号位 + 占位符 + 宽度
print(string.format('%+04d', 16)) -- +016
-- 占位符 + 小数位
print(string.format('%0.3f', -3)) -- -3.000
-- 字串裁剪
print(string.format('%.9s', 'hello lua hello java')) -- hello lua
-- 对齐标识 + 宽度数值 (默认为右对齐, 左填充.)
print(string.format('%9s', 'hi')) -- hi
print(string.format('%-9s', 'hi')) -- hi
- 模式匹配函数
find()
&gfind()
&gsub()
&gmatch()
--[[
字符串查找
在给定字符串中查找子串, 返回查找到的子串的开始和结束索引, 如果没有的话, 返回 nil
s: 给定字符串
pattern: 要查找的字符串
init: start_index 从给定字符串的哪个索引处开始查找
plain: 查找
]]
-- string.find(s, pattern [, init [, plain]])
print(string.find('hello lua lua', 'lua', 3)) -- 7 9
print(string.find('hello lua lua', 'world', 3)) -- nil
--[[
字符串替换
在源字符串中查找指定模式的字符串, 查找到的话, 用指定字符串对其进行替换, 返回替换后的字符串和成功配对的次数
没有chazhaodaodehua,不替换, 返回源字符串和 0
s: 源字符串
pattern: 查找模式
repl: 替换结果
注: 1) 当 repl为字符串时, repl将替换匹配到的字符串
2) 当 repl为 table时, 对每个匹配到的子串, 函数会试图寻找以其为 key值的 table中的元素, 并返回该元素,
该元素会被用作替换文本, 如果 table中没有对应的 key, 则不会发生替换
3) 当 repl为函数时, 每个成功配对的子字符串会作为参数传入到该函数中去, 如果函数返回了字符串或数字的值,
这个值会被用作替换文本, 如果函数没有返回, 则不会发生替换
n: 对前 n个匹配到的元素进行替换. 可选, 默认对匹配到的元素作全部替换
]]
-- string.gsub(s, pattern, repl [, n])
-- 简单情况, 匹配和替换都使用字符串
print(string.gsub('hello lua, hello python', 'hello', 'hi')) -- hi lua, hi python 2
print(string.gsub('hello lua, hello python', 'hello', 'hi', 1)) -- hi lua, hello python 1
print(string.gsub('hello lua, hello python', 'world', 'hi', 1)) -- hello lua, hello python 0
-- 替换模式改为 table
mytab = {
hello = 'echo'
}
print(string.gsub('hello lua, hello python', 'hello', mytab)) -- echo lua, echo python 2
print(string.gsub('hello lua, hello python', 'lua', mytab)) -- hello lua, hello python 1
print(string.rep('-', 30))
-- 替换模式改为 function
myfunc = function(param)
if param == 'hello' then
return 'echo'
end
end
print(string.gsub('hello lua, hello python', 'hello', myfunc)) -- echo lua, echo python 2
print(string.gsub('hello lua, hello python', 'lua', myfunc)) -- hello lua, hello python 1
print(string.rep('-', 30))
-- 复杂替换 (使用模式)
-- %w : 与任何字母/数字匹配
-- %s : 与空白字符匹配
-- + : 出现一次或多次
print(string.gsub("hello world", "(%w+)", "%1 %1")) -- hello hello world world 2
print(string.gsub("hello Lua", "(%w+)%s*(%w+)", "%2 %1")) -- Lua hello 1
string.gsub("hello world", "%w+", print) -- hello
world
print(string.gsub("hello lua", "(%w+)", mytab)) -- echo lua 2
-- 字符串匹配
--[[
获取字符串中的第一个配对. 成功配对时, 返回配对结果; 无法配对时, 返回 nil
s: 源字符串
pattern: 配对模式
init: 起始查找索引
]]
-- string.match(s, pattern [, init])
print(string.match('hello ', 'he')) -- he
print(string.match('hello ', 'world')) -- nil
print(string.match('hello ', '%w')) -- h
print(string.match('hello ', '%w+')) -- hello
print(string.match('hello ', '%s')) -- (返回一个空格)
-- 返回一个迭代器函数
-- string.gmatch(s, pattern)
s = 'hello lua, hello python, hello java'
print(string.gmatch(s, 'hello')) -- function: 0274dce0
for w in string.gmatch(s, '%a+') do
print(w)
end
-- output:
-- hello
-- lua
-- hello
-- python
-- hello
-- java
print(string.rep('-', 30))
mytab = {}
s = 'sdk1 = lua, sdk2 = python, sdk3 = java'
for k, v in string.gmatch(s, '(%w+%s?)=(%s?%w+)') do
mytab[k] = v
end
for k, v in pairs(mytab) do
print(k, v)
end
-- output:
-- sdk1 lua
-- sdk2 python
-- sdk3 java
-- Lua 支持的所有字符类
-- 单个字符: 与该字符自身匹配 (注: ^$()%.[]*+? 除外)
-- . : 与任何字符匹配
-- %a : 与任何字母匹配
-- %c : 与任何控制符匹配 (如:
)
-- %d : 与任何数字匹配
-- %l : 与任何小写字母匹配
-- %p : 与任何标点符号匹配
-- %s : 与空白字符匹配
-- %u : 与任何大写字母匹配
-- %w : 与任何字母/数字匹配
-- %x : 与任何十六进制匹配
-- %z : 与任何代表0的字符匹配
-- %x (此处 x是非字母非数字字符) : 与字符 x配对, 主要用来处理表达式中有功能的字符 (^$()%.[]*+?)的配对问题
-- 其实就是转义
-- [整个字符类] : 与任何 []中包含的字符类匹配, 例如 [%w_]与任何数字/字母/下划线匹配
-- [^整个字符类] : 与任何不包含在 []中的字符类匹配, 例如 [^%s]与任何非空白字符匹配
参考文章
1. 极客学院 OpenResty 最佳实践 - Lua String库
2. Lua string.format用法
3. Lua string(字符串)和强大的模式匹配功能