Lua 字符串操作

常用方法

  • 与 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


-- 关于 '\0' 字符串的说明
-- 在 C语言中: \0是转义字符, 代表空字符串, 对应的 ASCII码为 0, 通常用来作为字符串的结束标志
-- 在 lua中: \0

-- 这里不是很明白 \0, \00, \000有什么区别
print('\0', #'\0')          --      1
print('\00', #'\00')        --      1
print('\000', #'\000')      --      1
print('\0000', #'\0000')    --  0   2
print('\0\0', #'\0\0')      --      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 \n 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  : 与任何控制符匹配 (如: \n)
-- %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(字符串)和强大的模式匹配功能

猜你喜欢

转载自blog.csdn.net/dom4j_/article/details/80199434