您的位置:首页 > 编程语言 > Lua

lua string库函数详解、实例及lua正则表达式

2015-10-17 18:55 190 查看
写在前面:
--->lua中字符串索引从前往后是1,2,……,从后往前是......,-2,-1

     e.g: tmp = “abcd” ,tmp[1] =='a',tmp[2] =='b',tmp[-1] =='d',tmp[-2] =='c'.

--->string库中所有的function都不会直接操作字符串,只返回一个结果。
--->两种调用方式:
     a = '\t a bc d '
     string.len(a)
     a:len()   -- 与 string.len(a) 效果相同, 其他string库函数也类似

lua, string库函数列表:

    string.find
    string.format

    string.gmatch

    string.gsub

    string.sub

    string.len

    string.match

    string.rep

    string.reverse

    string.pack/string.unpack/string.packsize

    string.upper

    string.lower

    string.byte

    string.char

    string.dump

lua, string库函数解释及实例:

---> string.find

    函数原型:string.find(str, pattern [, init [, plain]] )

    参数说明:

        str: 源字符串
        pattern: 待搜索模式串
        init: 查找的起始位置(可选)
        plain: 用法待确定,未用过

     函数应用实例:

         -- 搜索存在的字符串

         print(string.find("wo de jia xiang", 'de') )  -- 输出:4 5

         -- 搜索不存在的字符串

         print(string.find("wo de jia xiang", 'no') )  -- 输出:nil

         -- 模式匹配

          print (string.find(" name = Anna ",  "(%a+)%s*=%s*(%a+)") ) -- 输出 2 12 name Anna 

          解释: 如果 find 的第二个参数使用了某种匹配模式, 并且模式串里面带括号。 那么表示会“捕捉”括号括起来的模式匹配到的字符串。 捕捉到后会把他们作为返回值返回,本例中捕捉了两次, 故find 多返回了两个值,“2”和“12”分别表示捕捉到第一个字符串的起始位置和最后一个字符串的结束位置。

         -- lua正则表达式的说明(正则表达式可不仅仅可用在find函数,其他可用模式匹配的函数也是通用的):
         1. Lua支持的所有字符类:
            
.     任意字符
            %a      字母
           %c
     控制字符
           %d
     数字
           %l
     小写字母
           %p
     标点字符
           %s
     空白符
           %u
     大写字母
           %w
     字母和数字
           %x
     十六进制数字
           %z
     代表0的字符
         上面字符类的大写形式表示小写所代表集合的补集。例如,'%A'非字母的字符:
         
print(string.find("up-down!", "%A")) -- 输出:3   3

          2. 模式匹配的特殊字符   ( ) . % + - * ? [ ^ $

          解释:`%′用作特殊字符的转义字符,因此 '%.' 匹配点; '%%'匹配字符`%′.转义字符`%′不仅可以用来转义特殊字符,还可以用于所有的非字母的字符。当对一个字符有疑问的时候,为安全起见请使用转义字符转义它。

          对Lua而言,模式串就是普通的字符串。他们和其他的字符串没有区别,也不会受到特殊对待。只有他们被用作模式串用于函数的时候,`%′才作为转义字符。所以,如果你需要在一个模式串内放置引号的话,你必须使用在其他的字符串中放置引号的方法来处理,使用`\′转义引号,`\′是Lua的转义符。你可以使用方括号将字符类或者字符括起来创建自己的字符类(译者:Lua称之为char-set,就是指传统正则表达式概念中的括号表达式)。比如,'[%w_]'将匹配字母数字和下划线,'[01]'匹配二进制数字,'[%[%]]'匹配一对方括号。

         下面的例子统计文本中元音字母出现的次数:

         _, nvow = string.gsub("wo men de zu guo", "[AEIOUaeiou]", "")   --
nvow == 6

         在char-set中可以使用范围表示字符的集合,第一个字符和最后一个字符之间用连字符连接表示这两个字符之间范围内的字符集合。大部分的常用字符范围都已经预定义好了,所以一般不需要自己定义字符的集合。比如,'%d'表示'[0-9]';'%x'表示'[0-9a-fA-F]'。然而,如果你想查找八进制数,你可能更喜欢使用'[0-7]'而不是'[01234567]'。我们可以在字符集(char-set)的开始处使用`^′ 表示其补集: 例如,'[^0-7]' 匹配任何不是八进制数字的字符; '[^\n]'匹配任何非换行符户的字符。注意,可以使用大写的字符类表示其补集:
'%S'比'[^%s]'要简短些,但是其功能是一样的.

         Lua的字符类依赖于本地环境,所以'[a-z]'可能与'%l'表示的字符集不同。在一般情况下,后者包括`ç´ 和`ã´,而前者没有。应该尽可能的使用后者来表示字母,除非出于某些特殊考虑,因为后者更简单、方便、更高效。

        可以使用修饰符来修饰模式增强模式的表达能力,Lua中的模式修饰符有四个:
              +     匹配前一字符1次或多次
              *      匹配前一字符0次或多次
              -      匹配前一字符0次或多次
              ?      匹配前一字符0次或1次

         解释:
       
       
`+′ 匹配一个或多个字符,她总是进行最长的匹配. 例如,
                   模式串
'%a+'匹配一个或多个字母或者一个单词 :
                       print(string.gsub("one,
and two; and three", "%a+", "word"))     --输出: word, word word; word word    5
                  '%d+'匹配一个或多个数字
(整数):
                       print(string.find("the
number 1298 is even", "%d+")) --输出:12  15
              `*′
`+′类似, 但是他匹配一个字符0次或多次出现.一个典型的应用是匹配空白。比如,为了匹配一对圆括号()或者()之间的空白,可以使用'%(%s*%)'. ( '%s*'用来匹配0个或多个空白.由于圆括号在模式中有特殊的含义,所以我们必须使用`%′转义他.)再看一个例子,'[_%a][_%w]*'匹配Lua程序中的标示符:字母或者下划线开头的字母下划线数字序列; 再例如,print(string.gsub("one,
and two; and three", "%a*", "word"))     --输出: wordword,word wordword wordword;word wordword wordword    12
              `-′与`*′,都匹配一个字符的0次或多次出现,但是他进行的是最短匹配。比如,如果你使用模式'[_%a][_%w]-'来查找标示符,你将只能找到第一个字母,因为'[_%w]-'永远匹配空。另一方面,假定你想查找C程序中的注释,很多人可能使用'/%*.*%*/'
(也就是说 ""). 然而,由于'.*'进行的是最长匹配,这个模式将匹配程序中第一个""之间所有部分:例如,print(string.gsub("one, and two; and three", "%a-", "word"))       --输出(每个字母都会被"word"替换): wordowordnwordeword,word wordawordnworddword wordtwordwwordoword;word
wordawordnworddword wordtwordhwordrwordewordeword    24
              `?′
匹配一个字符0次或1次.举个例子,假定我们想在一段文本内查找一个整数,整数可能带有正负号。 模式'[+-]?%d+'符合我们的要求,她可以匹配 像 "-12", "23" 和 "+1009"等数字. '[+-]'是一个匹配`+′或者 `-′的字符类;接下来的 `?′意思是匹配前面的字符类0次或者1次.
              
再例如:print(string.gsub("one, and two; and three", "%a?", "word"))       --输出(每个字母都会被"word"替换): wordowordnwordeword,word wordawordnworddword wordtwordwwordoword;word wordawordnworddword wordtwordhwordrwordewordeword  
 24

       与其他系统的模式不同的是,Lua中的修饰符不能用字符类;不能将模式分组然后使用修饰符作用这个分组。比如,没有一个模式可以匹配一个可选的单词(除非这个单词只有一个字母)。下面我将看到,通常你可以使用一些高级技术绕开这个限制。

以`^′开头的模式只匹配目标串的开始部分,相似的,以`$′结尾的模式只匹配目标串的结尾部分。这不仅可以用来限制你要查找的模式,还可以定位(anchor)模式。例如:
       检查字符串s是否以数字开头
: if string.find(s, "^%d") then ...
       检查字符串s是否是一个整数
: if string.find(s, "^[+-]?%d+$") then ...  -- 这里'$'表示到字符串末尾的意思

       '%b'用来匹配对称的字符.常写为'%bxy',x和y是任意两个不同的字符;x作为匹配的开始,y作为匹配的结束。

                 例如, '%b()'匹配以`(′开始, 以`)′结束的字符串: print(string.gsub("a (enclosed (in) parentheses) line", "%b()", ""))  -- 输出:a  line    1
         注: 常用的这种模式有: '%b()', '%b[]', '%b%{%}',和'%b<>'。我们可以使用任何字符作为分隔符。

---> string.format

        
函数应用实例:

             print(string.format("%0.2f", 34.2344))  -- 输出:34.23

         更多用法

            %c - 接受一个数字, 并将其转化为ASCII码表中对应的字符

            %d, %i - 接受一个数字并将其转化为有符号的整数格式

            %o - 接受一个数字并将其转化为八进制数格式

            %u - 接受一个数字并将其转化为无符号整数格式

            %x - 接受一个数字并将其转化为十六进制数格式, 使用小写字母

            %X - 接受一个数字并将其转化为十六进制数格式, 使用大写字母

            %e - 接受一个数字并将其转化为科学记数法格式, 使用小写字母e

            %E - 接受一个数字并将其转化为科学记数法格式, 使用大写字母E %f - 接受一个数字并将其转化为浮点数格式

            %g(%G) - 接受一个数字并将其转化为%e(%E, 对应%G)及%f中较短的一种格式

            %q - 接受一个字符串并将其转化为可安全被Lua编译器读入的格式

            %s - 接受一个字符串并按照给定的参数格式化该字符串

     以下是一些例子:

           string.format("%%c: %c",83)  -- 输出:S

           string.format("%+d", 17.0)  -- 输出:+17

           string.format("%05d", 17)  -- 输出:00017

           string.format("%o", 17)  -- 输出:21

           string.format("%u", 3.14)  -- 输出:3

           string.format("%x", 13)  -- 输出:d

           string.format("%X", 13)  -- 输出:D

           string.format("%e", 1000)  -- 输出:1.000000e+03

           string.format("%E", 1000)  -- 输出:1.000000E+03

           string.format("%6.3f", 13)  -- 输出:13.000

           string.format("%q", "One\nTwo")  -- 输出:"One\Two"

           string.format("%s", "monkey")  -- 输出:monkey

           string.format("%10s", "monkey")  -- 输出: monkey

           string.format("%5.3s", "monkey")  -- 输出: mon</font>          



[b]---> tring.gmatch[/b]

         函数说明:返回一个迭代函数 可以遍历出现的目标字符串

         函数应用实例:

                 for w in string.gmatch("hello world from Lua", "%a+") do

                     print(w)

                end

[b]                -- [/b]输出[b]:[/b]

[b]                [/b]hello
[b]                [/b]world
[b]                [/b]from
[b]                [/b]Lua

[b]---> string.gsub[/b]

        函数原型:string.gsub(s, pat, repl [, n])

        函数功能:返回一个和pat匹配,并且用repl替换的副本。repl可以是string、table和functin。

        参数说明:

            s: 源字符串

            pat: 即 pattern, 匹配模式

            repl: replacement, 将 pat 匹配到的字串替换为 repl

            [, n]:  表示只看源字符串的前 n 个字符(可选)
         注意:gsub 调用之后返回 两个值, 一个是替换后的字符串, 第二个是替换的次数

         函数应用实例:

             function trim(s) return (string.gsub(s, "^%s*(.-)%s*$", "%1"))end  

            ----然后调用:  

            s='\t a bc d '  

            print(trim(s))  -----输出: a bc d, 开头的 \t, 结尾的空格 都被 trim 掉了



            这里有几点要解释:

            1. return (string.gsub(...)), 注意 string.gsub 外面还有一层括号。 事实上, gsub 调用之后返回 两个值, 一个是替换后的字符串, 第二个是替换的次数。 而一旦外面加了括号, 就只返回第一个值, 即替换后的字符串。如果去掉 ^跟$, 那么就不是匹配整个字串, 在 (.-) 的作用下, 输出就成了: abcd 连在一起

            2. 匹配模式字串 "^...$", 表示匹配的是整个字符串。 ^ 表开头, $ 表示结尾。在这里, (.-) 的效果跟 (.*) 的效果应该是一样的, 因为反正是从字串开头匹配到结尾。

            3. 拷贝捕获(%1-%9):我们可以在模式中使用向前引用,'%d'(d代表1-9的数字)表示第d个捕获的拷贝。

            例如,假定你想查找一个字符串中单引号或者双引号引起来的子串,你可能使用模式 '[\"\'].-[\"\']',但是这个模式对处理类似字符串 "it's all right" 会出问题。为了解决这个问题,可以使用向前引用,使用捕获的第一个引号来表示第二个引号:  print(string.find("abc \"it\'s  a cat\"",  "([\"\'])(.-)%1"))     -- 输出:5    17    "    it's  a cat

           再例如,print(string.gsub("abcd", "(.)(.)", "%2%1"))     -- 输出:badc    2

                          print(string.gsub("abcd", "(.)(.)", "%1"))     -- 输出:ac    2

                          print(string.gsub("abcd", "(.)(.)", "%1%1"))     -- 输出:aacc    2

                          print(string.gsub("abcd", "(.)(.)", "a"))     -- 输出:aa    2

                          print(string.gsub("abcd", "(.)(.)", "mnk"))    -- 输出:mnkmnk    2

[b]---> string.sub
[/b]

[b] [/b]        函数说明:string.sub(s,i,j)      函数截取字符串s的从第i个字符到第j个字符之间的串,j可省略,省略后表示到字符串末尾。

         函数应用实例:print(string.sub("abcde", 2,-2))   -- 输出:bcd

[b][b][b]                                  [/b][/b][/b]  
print(string.sub("abcde", 2))   -- 输出:bcd[b]e
[/b]

[b]---> string.len[/b]

        函数说明:获取字符串长度

        函数应用实例: print(string.len("women")) -- 输出:5[b]
[/b]

[b]---> string.match[/b]

        函数说明:与string.find类似 但是返回匹配的子串

        函数应用实例: print(string.match("today is 19/2/2001 11/21/20011","%d+/%d+/%d+"))  -- 输出:19/2/2001

[b]---> string.rep[/b]

        函数原型:string.rep(s, n)

        函数说明:返回重复n次字符串s的串,你使用string.rep("a", 2^20)可以创建一个1M bytes的字符串

        函数应用实例: print(string.rep("abc", 3))  -- 输出:abcabcabc

[b]---> string.reverse[/b]

        函数原型:string.reverse(str)

        函数说明:反转字符串

        函数应用实例: print(string.reverse("a b c "))  -- 输出: c b a

[b][b]         注意:中文反转后是乱码的情况
[/b]
[/b]
[b]---> string.pack/string.unpack/[b][b][b]string.[/b]packsize  -- 使用较少,粗略介绍[/b][/b][/b]

[b][b][b]         [b]pack: [/b][/b][/b][/b]lua 5.3 提供的 string.pack 基本就是非官方的 struct 库,使用它可以节省不少对二进制流的处理代码。

         [b]unpack: [/b]这个函数从 lua 5.2 开始就从全局函数移到了 table 下,只是因为部分同学的习惯问题而一直没有改过来。这次 lua 5.3 把它从全局变量里删掉了,就逼大家改习惯了。

[b][b][b][b][b]        packsize:[/b][/b][/b][/b][/b]大小处理

[b][b][b][/b][/b]
[/b]

[b]---> string.upper[/b]

        函数说明:字母小写变大写

        函数应用实例: print(string.upper("姓Wang"))-- 输出:姓WANG

[b][/b]

[b]---> string.lower[/b]

        函数说明:字母大写变小写

        函数应用实例: print(string.lower("姓Wang"))-- 输出:姓wang[b]
[/b]

[b]---> string.byte[/b]

[b] [/b]        函数说明:string.byte(string [,pos]):返回第pos个字符的整数表示形式.如a为97.最多只能指定两个字符

         函数应用实例:print(string.byte("abcd", 1)) -- 输出:97

                                     print(string.byte("abcd", 1, 2)) -- 输出:97    98

                                     print(string.byte("abcd", 1, 2, 3)) -- 输出:97    98

[b]---> string.char[/b]

[b] [/b]        函数说明:string.char(i1,i2...):i1,i2为整型,将i1,i2..等转化为对应的字符然后连接成字符串,并返回.如i1=97则返回a.

         函数应用实例:print(string.char(98, 99, 100, 101))  -- 输出:bcde


[b]---> string.dump[/b]

        函数说明:string.dump(function)。返回指定函数的二进制代码(函数必须是Lua函数,并且没有up value)

       函数应用实例:将一个函数转换成二进制码,输出;再换回来,输出;再执行

                  function DumpTest()

                     print("string.dump test")

                 end

                 local a = string.dump(DumpTest) --将函数DumpTest转换成二进制码

                 local b = loadstring(a)

                 print(b)    --loadstring(string)可以用来运行一段字符串代码.简单来说,就是把字符串转换成代码。

                 b()

[b][b]          [/b][/b]运行结果:

                 function: 0xb74e7bd0

                 string.dump test

       注:string.dump可以实现函数序列化,函数可以传递了,甚至把函数传递到另一个进程都可以的。可以实现在其他作用域访问不同的地方的函数。更多的是做框架的时候用的功能,一般写逻辑代码应该用不到。

结束语:本文部分内容来自网上资料通过个人整理得来,供大家参考


   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息