zoukankan      html  css  js  c++  java
  • 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
    
    
    -- 关于 '' 字符串的说明
    -- 在 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(字符串)和强大的模式匹配功能

  • 相关阅读:
    HTML学习记录之HTML组成原理 PHP学习铺垫
    最长上升子序列(Longest increasing subsequence)
    进程保护(二)
    进程保护(一)
    屏幕广播的实现(三)
    vs2010 调试快捷键
    [整理]C#.Net的常见面试试题附答案(ZT)
    C# 中处理字符串常用的函数及方法详细说明
    Linux 系统下 /etc/group 档案结构
    C# Thread 多种写法总结
  • 原文地址:https://www.cnblogs.com/bobo132/p/13950363.html
Copyright © 2011-2022 走看看