Lua string库整理(v5.1)

作者: chiguozi | 来源:发表于2016-08-20 00:12 被阅读470次

    string库提供了字符串处理的通用函数。 例如字符串查找、子串、模式匹配等。 当在 Lua 中对字符串做索引时,第一个字符从 1 开始计算(而不是 C 里的 0 )。 索引可以是负数,它指从字符串末尾反向解析。 即,最后一个字符在 -1 位置处,等等。
    字符串库中的所有函数都在表string 中。 它还将其设置为字符串元表的__index 域。 因此,你可以以面向对象的形式使用字符串函数。 例如,string.byte(s,i) 可以写成 s:byte(i)。

    字符串库假定采用单字节字符编码

    string.byte(s[,i[,j]])

    返回字符串s[i]. s[i+1],...,s[j]的内部数字编码。i的默认值是1,j的默认值是i

    s = 'abc'
    print(string.byte(s))
    print(string.byte(s,2))
    print(string.byte(s,2,3))
    
    Output:
    97
    98
    98  99
    

    string.char(...)

    接收零或更多的整数。 返回和参数数量相同长度的字符串。 其中每个字符的内部编码值等于对应的参数值。

    print(string.char(98, 99, 100))
    
    Output:
    bcd
    

    string.dump(function)

    返回包含有以二进制方式表示的(一个 二进制代码块 )指定函数的字符串。 之后可以用 loadstring 调用这个字符串获得 该函数的副本。

    function必须是没有upvalues的lua函数。

    function dump()
        print("dump test  ")
    end
    
    s = string.dump(dump)
    print(s)
    
    func = loadstring(s)
    func()
    
    Output:
    �LuaQ
    dump test  
    

    lua 5.3 有改动


    string.find(s, pattern [,init [, plain]])

    查找第一个字符串 s 中匹配到的 pattern 如果找到一个匹配,find 会返回 s 中关于它起始及终点位置的索引; 否则,返回 nil。 第三个可选数字参数 init 指明从哪里开始搜索; 默认值为 1 ,同时可以是负值。 第四个可选参数 plain 为 true 时, 关闭模式匹配机制。 此时函数仅做直接的 “查找子串”的操作, 而 pattern 中没有字符被看作魔法字符。 注意,如果给定了 plain ,就必须写上 init。

    如果在模式中定义了捕获,捕获到的若干值也会在两个索引之后返回。

    local s = "abcdefg"
    print(string.find(s,"(c)"))
    print(string.find(s,"(c)"),1, true)
    
    Output:
    3   3   c
    3   1   true
    

    string.format(formatstring, ...)

    返回不定数量参数的格式化版本, 格式化串为第一个参数(必须是一个字符串)。 格式化字符串遵循 ISO C 函数 sprintf 的规则。 不同点在于选项 *, h, L, l, n, p 不支持, 另外还增加了一个选项 q。 q 选项将一个字符串格式化为两个双引号括起,对内部字符做恰当的转义处理的字符串。 该字符串可以安全的被 Lua 解释器读回来。 例如,调用

    string.format('%q', 'a string with "quotes" and \n new line')

    会产生字符串:

    "a string with \"quotes\" and \new line"

    E, e, f, G, and g 都期待一个对应的数字参数。 选项 c, d, i, o, u, X, and x 则期待一个整数。 选项 q 期待一个字符串; 选项 s 期待一个没有内嵌零的字符串。

    print(string.format("%d, %s", 1, "a"))
    
    Output:
    1, a
    

    string.gmatch(s, pattern)

    返回一个迭代器函数。 每次调用这个函数都会继续以 pattern 对 s 做匹配,并返回所有捕获到的值。 如果 pattern 中没有指定捕获,则每次捕获整个 pattern。

    对这个函数来说,模板前开始的 '^' 不会当成锚点。因为这样会阻止迭代。

    s = "hello world from Lua"
    for w in string.gmatch(s, "%a+") do
        print(w)
    end
    
    Output:
    hello
    world
    from
    Lua
    

    string.gsub(s, pattern, repl [, n])

    将字符串 s 中,所有的(或是在 n 给出时的前 n 个) pattern 都替换成 repl ,并返回其副本。 repl 可以是字符串、表、或函数。 gsub 还会在第二个返回值返回一共发生了多少次匹配。 gsub 这个名字来源于 Global SUBstitution

    如果 repl 是一个字符串,那么把这个字符串作为替换品。 字符 % 是一个转义符: repl 中的所有形式为 %d 的串表示 第 d 个捕获到的子串,d 可以是 1 到 9 。 串 %0 表示整个匹配。 串 %% 表示单个 %。

    如果 repl 是张表,每次匹配时都会用第一个捕获物作为键去查这张表。

    如果 repl 是个函数,则在每次匹配发生时都会调用这个函数。 所有捕获到的子串依次作为参数传入。

    任何情况下,模板中没有设定捕获都看成是捕获整个模板。

    如果表的查询结果或函数的返回结果是一个字符串或是个数字, 都将其作为替换用串; 而在返回 falsenil 时不作替换 (即保留匹配前的原始串)。

    -- 匹配字符转
    -- 先匹配hello, %1 为匹配值,  将hello 替换为hello hello
    -- 匹配world时 同理
    print(string.gsub("hello world", "(%w+)", "%1 %1"))
    print(string.gsub("hello world", "(%w+)", "%0 %0",1))
    
    Output:
    hello hello world world 2
    hello hello world   1
    
    -- 替换函数
    print(string.gsub("4+5 = $return 4+5$", "%$(.-)%$", 
        function (s)
            print(s)
            return loadstring(s)()
        end))
    
    Output:
    return 4+5
    4+5 = 9 1
    
    --表
    local t = {name="lua", version="5.3"}
    print(string.gsub("$name-$version.tar.gz", "%$(%w+)", t))
    
    Output:
    lua-5.3.tar.gz  2
    

    string.len(s)

    接收一个字符串,返回其长度。 空串 "" 的长度为 0 。 内嵌零也统计在内,因此 "a\000bc\000" 的长度为 5 。

    print(string.len("hello world \0"))
    
    Output:
    13
    

    string.lower(s)

    接收一个字符串,将其中的大写字符都转为小写后返回其副本。 其它的字符串不会更改。 对大写字符的定义取决于当前的区域设置。

    print(string.lower("HeLLo World"))
    
    Output:
    hello world
    

    tring.match(s, pattern [, init])

    在字符串 s 中找到第一个能用 pattern匹配到的部分。 如果能找到,match 返回其中的捕获物; 否则返回 nil 。 如果 pattern 中未指定捕获, 返回整个 pattern 捕获到的串。 第三个可选数字参数 init 指明从哪里开始搜索; 它默认为 1 且可以是负数。

    print(string.match("hello world", "(%w+)"))
    print(string.match("hello world", "(%w+)", -1))
    
    Output:
    hello
    d
    

    string.rep(s, n)

    返回n个字符串s连在一起的字符串

    print(string.rep("abc", 2))
    
    Output:
    abcabc
    

    lua 5.3 有改动


    string.reverse(s)

    返回字符串 s 的翻转串。

    print(string.reverse("abc"))
    
    Output:
    cba
    

    string.sub(s)

    返回 s 的子串, 该子串从 i 开始到 j 为止; i 和 j 都可以为负数。 如果不给出 j ,就当它是 -1 (和字符串长度相同)。 特别是, 调用 string.sub(s,1,j) 可以返回 s 的长度为 j 的前缀串, 而 string.sub(s, -i) 返回长度为 i的后缀串。

    print(string.sub("Hello World", 5))
    print(string.sub("Hello World", -3))
    
    Output:
    o World
    rld
    

    string.upper(s)

    接收一个字符串,将其中的小写字符都转为大写后返回其副本。 其它的字符串不会更改。 对小写字符的定义取决于当前的区域设置。

    print(string.upper("Hello World"))
    
    Output:
    HELLO WORLD
    

    匹配模式

    字符类:

    字符类 用于表示一个字符集合。 下列组合可用于字符类:

    • **x: *(这里 x 不能是 魔法字符 ^$()%.[]+-? 中的一员) 表示字符 x 自身。

    • **.: **(一个点)可表示任何字符。

    • **%a: **表示任何字母。

    • **%c: **表示任何控制字符。

    • **%d: **表示任何数字。

    • **%g: **表示任何除空白符外的可打印字符。

    • **%l: **表示所有小写字母。

    • **%p: **表示所有标点符号。

    • **%s: **表示所有空白字符。

    • **%u: **表示所有大写字母。

    • **%w: **表示所有字母及数字。

    • **%x: **表示所有 16 进制数字符号。

    • **%x: **(这里的 x 是任意非字母或数字的字符) 表示字符 x。 这是对魔法字符转义的标准方法。 所有非字母或数字的字符 (包括所有标点,也包括非魔法字符) 都可以用前置一个 '%' 放在模式串中表示自身。

    • **[set]: **表示 set 中所有字符的联合。 可以以 '-' 连接,升序书写范围两端的字符来表示一个范围的字符集。 上面提到的 %x 形式也可以在 set 中使用 表示其中的一个元素。 其它出现在 set 中的字符则代表它们自己。 例如,[%w_] (或 [_%w]) 表示所有的字母数字加下划线), [0-7] 表示 8 进制数字, [0-7%l%-] 表示 8 进制数字加小写字母与 '-' 字符。

      交叉使用类和范围的行为未定义。 因此,像 [%a-z] 或 [a-%%] 这样的模式串没有意义。

    • **[^set]: **表示 set 的补集, 其中 set 如上面的解释。

    所有单个字母表示的类别(%a,%c,等), 若将其字母改为大写,均表示对应的补集。 例如,%S 表示所有非空格的字符。

    如何定义字母、空格、或是其他字符组取决于当前的区域设置。 特别注意:[a-z] 未必等价于 %l 。

    模式条目:

    模式条目 可以是

    • 单个字符类匹配该类别中任意单个字符;
    • 单个字符类跟一个 '', 将匹配零或多个该类的字符。 这个条目总是匹配尽可能长的串*;
    • 单个字符类跟一个 '+', 将匹配一或更多个该类的字符。 这个条目总是匹配尽可能长的串
    • 单个字符类跟一个 '-', 将匹配零或更多个该类的字符。 和 '' 不同, 这个条目总是匹配尽可能短的串*;
    • 单个字符类跟一个 '?', 将匹配零或一个该类的字符。 只要有可能,它会匹配一个;
    • %n, 这里的 n 可以从 1 到 9; 这个条目匹配一个等于 n 号捕获物(后面有描述)的子串。
    • %b_xy_, 这里的 xy 是两个明确的字符; 这个条目匹配以 x 开始 y 结束, 且其中 xy 保持 平衡 的字符串。 意思是,如果从左到右读这个字符串,对每次读到一个 x+1 ,读到一个 y-1, 最终结束处的那个y 是第一个记数到 0 的 y。 举个例子,条目 %b() 可以匹配到括号平衡的表达式。
    • %f[set], 指 边境模式; 这个条目会匹配到一个位于 set 内某个字符之前的一个空串, 且这个位置的前一个字符不属于 set 。 集合 set 的含义如前面所述。 匹配出的那个空串之开始和结束点的计算就看成该处有个字符 '\0' 一样。

    模式:

    模式 指一个模式条目的序列。 在模式最前面加上符号 '^' 将锚定从字符串的开始处做匹配。 在模式最后面加上符号 '$' 将使匹配过程锚定到字符串的结尾。 如果 '^' 和 '$' 出现在其它位置,它们均没有特殊含义,只表示自身。

    捕获:

    模式可以在内部用小括号括起一个子模式; 这些子模式被称为 捕获物。 当匹配成功时,由 捕获物 匹配到的字符串中的子串被保存起来用于未来的用途。 捕获物以它们左括号的次序来编号。 例如,对于模式 "(a(.)%w(%s))" , 字符串中匹配到 "a(.)%w(%s)" 的部分保存在第一个捕获物中 (因此是编号 1 ); 由 "." 匹配到的字符是 2 号捕获物, 匹配到 "%s*" 的那部分是 3 号。

    作为一个特例,空的捕获 () 将捕获到当前字符串的位置(它是一个数字)。 例如,如果将模式 "()aa()" 作用到字符串 "flaaap" 上,将产生两个捕获物: 3 和 5 。

    参考链接:http://cloudwu.github.io/lua53doc/manual.html

    相关文章

      网友评论

        本文标题:Lua string库整理(v5.1)

        本文链接:https://www.haomeiwen.com/subject/hfxisttx.html