美文网首页
lua入门笔记7 字符串库

lua入门笔记7 字符串库

作者: Charon_ted | 来源:发表于2019-09-25 16:12 被阅读0次

    基础知识

    Lua中的stringc#中相同,string类型的值一旦改变,便要为新值开辟空间,并指向此空间。也就是说每次对string变量进行更改操作时返回的是一个新的值,下面的函数中就不再过多去说明了。

    1.基础字符串函数

    • string.rep(s,n)s:rep(n): 可以返回字符串重复n此的结果。例
    s="abc"
    print(s:rep(3))  -->abcabcabc
    
    • string.lower(s) 将所有大写转换为小写
    • string.upper(s)将所有小写转为大写
    • string.sub(s,i,j) 从字符串s中提取第i道第j个字符,还可以使用负数。-1代表倒数第一个字符,-2代表倒数第二个字符(从1开始)
    • string.char() 用于将输入的整数转换为对应的ASCII码表中的值,允许一个或多个参数如
    print(string.char(97))        -->
    print(string.char(98,99,100))  -->bcd
    
    • string.byte() 用途和string.char()相反,将对应的值转换为ASCII表中对应的数组
    print(string.btye("abc"))     -->97
    print(string,btye("abc"),3)  -->99 输出第三个字符的值,c ==> 99
    print(string,btye("abc"),-1)  -->99 输出最后一个字符的值,c ==> 99
    print(string.btye("abc"),1,-1)  -->97 98 99 输出从第一个到最后一个 
    
    • string.format() 格式化字符串和c语言中的print函数的规则基本相同
      %d:十进制 %x:十六进击 %o:八进制 %f浮点数 %s string 这里还可以在中间加入一些格式,如
    print(string.format("pi=%4f",math.pi))     -->3.14
    d=5;m=11;y=1990
    print(string.format("%02d/%0d/%04d",d,m,y))     -->05/11/1990
    

    其他还有很多这里只是简单地举几个例子。

    2.模式匹配函数

    Lua中由于考虑大小,没有支持正则表达式。而采用了自己的模式匹配。

    • 1. string.find函数

    string.find函数用于在一个给定的目标字符串中搜索一个模式。最简单的是搜索单词。如果赵傲这个单词,他就会返回单词的其实索引和结束所用,如果没找到则返回nil

    s="hello world"
    i,j=string.find(s,"hello")   
    print(i,j)         -->1,5
    print(string.sub(s,i,j))      --> hello
    print(string.find(s,"world"))    -->7 11
    i j=string.find("l")
    print(i,j)                  -->3  3
    print(string.find("s","lll"))    -->nil
    

    如果匹配成功,就可以用string,find的返回值结果来调用string.sub来提取出目标字符串中匹配于该模式的那部分子串。
    string.find还有一个可选的第三参数,他是一个索引,告诉函数应从目标字符串的那个位置开始搜索。

    • 2. string.math函数

    函数string.math和函数string.find在某种意义上很相似,它也是用一个在字符串中搜索的一种模式。不同的是,string.math返回的是目标字符串中模式匹配的那部分子串,而并非位置。
    对于固定的模式,该函数可能没有什么意义例如"hello"。但当使用变量模式是,它的特性就显现出来了。

    date="today is 17//1990"
    d=string.math(date,"%d+/%d+/%d+")      -->这里具体含义之后再具体讲解
    print(d)    17/7/1990
    
    • 3. string.gsub函数

    string.gusb函数有3个参数:目标字符串、模式、替换字符串 作用就是将所有出现该模式的地方替换为替换字符串

    s=string.gsub("lua is cute","cute","great" )
    print(s)                              -->lua is great
    s=string.gsub("all lii","l","x")
    print(s)                        -->axx xii
    string=string,gsub("lua is great","Sol","Sun")
    print(s)          -->lua is great
    

    另外还有可选的第四个参数,可以限制替换的次数

    s=string.gsub("all lii","l","x",1)
    print(s)              --> axl lii
    s=string.gsub("all lii","l","x",2)
    print(s)              -->axx lii
    

    函数是string.gsub还有一种结果,即实际替换的次数,例如下面就是一种统计字符串中空格数量的简单方法

    s="this is a lua string"
    count=select(2,string.gsub(s," "," "))    ==>s,count=string.gsub(s," "," ")  
    
    • 4. string.gmatch函数

    string.gmatch会返回一个函数。通过这个函数可以遍历到一个字符串中所有出现指定摸式的地方。

    words={}
    for w in string.gamtch(s,"%a+") do
      words[#words+1]=w
    end
    

    其中模式"%a+"表示匹配一个或多个字母字符的序列(也就是单词),这里会遍历其中所有的单词,并存入其中。在模式中"点"具有特殊的意义,因此若要表示一个点必须写为"%."

    3 模式

    介意用字符分类创建更多有用的模式。字符分类就是模式中的一项。可以与一个热顶级和中的任意字符相匹配。例如分类"%d"可匹配任意数字。例如可以用
    "%d%d/%d%d/%d%d%d%d" 来搜索符合"dd/mm/yyyy"格式的日期

    s="deadline is 30/05/1999,firm"
    date="%d%d/%d%d/%d%d%d%d"
    print(string.sub(s,string.find(s,data)))      -->30/05/1999
    

    下面是所有的字符分类

    字符 意义
    . 所有字符
    %a 字母
    %c 控制字符
    %d 数字
    %l 小写字母
    %p 标点符号
    %s 空白字符
    %u 大写字母
    %w 字母和数字字符
    %x 十六进制数字
    %z 内部表示为0的字符

    这些分类的大写行使表示他们的补集,例如"%A"表示所有非字母字符

    print(string.sub("hello, up-down!","%A",".'))   
     -->hello..up.down.  4 返回两个值一个是替换之后的string 一个是替换的次数
    

    在模式里,还有一些字符串被称为“魔法字符”他们有着特殊的含义。这些魔法字符有
    { } . % + - * ? [ ] ^ $
    字符串%作为这些魔法字符的转义符,例如"%."表示匹配一个点 "%%"表示匹配字符"%" 不仅可以把"%"用于魔法字符,还可以用于其他所有非字母数字的字符。当不确定某个字符是不是需要被转义是,应该直接前置一个转义符。
    对于lua来说,模式就是普通的字符串。并想起他字符串一样遵循相同的规则。只有模式函数才会解释它们,此时参会将"%"当做转义符来处理。
    在一堆放括号内将不同的字符分类或者单个字符组合起来,即可创造出属于用户自己的字符分类,这种新的字符分类叫做字符集(char-set)。例如,字符集["%w_"]表示同时匹配字母、数字和下划线。字符集[01]表示匹配二进制数字 字符集[%[%]]表示匹配方括号本身。如果需要统计一段文本中元音的数量,可以这么写

    nvow=select(2,string.gsub(text,"[AEIOUaeiou]",""))
    

    在字符集中表示一段字符范围的做法是写出自付范围的第一个字符和最后一个字符并用横线连接它们,但这种形式用的较少因为大部分常用的字符范围都已经预定义好了。如[0-9]即为%d
    [0-9a-fA-F]则为"%x"不过如果需要查找一个8进制的数字,那么可以写[0-7]而不是[01234567]。在一个字符集前加一个'^'即可表示这个字符集的补集。例如[^0-7]表示所有非八进制数字的字符。而模式[^\n]则表示了除了换行符之外的其他字符。对于简单地分类,使用大写形式也可以得到他的补集,"%S"显然比[^%s]简答
    也可以通过修饰符来藐视模式中的重复可选部分。lua提供四种修饰符

    修饰符 意义
    + 重复1次或多次
    * 重复0次或多次
    - 也是重复0次或多次
    ? 可选部分(出现0或1次)

    “+”修饰符科普配属于字符串分类的一个或多个字符。他总是获取与模式相匹配的最长序列,模式 "%a+"表示一个或多个字母,即单词:

    print(string.gsub("one, and two ;and three","&a+","word"))
    -->word, word word; word word  (将所有单词换成 word)
    

    模式"%d+" 匹配一个或多个数组(一个整数)

    print(string.math("the number 1298 is even","%d+"))     -->1298
    

    修饰符"*" 类似于"+",但它还接受出现0次的情况。一种典型用途是匹配一个模式不同部分之间的空格。 比如说像匹配()或者( ) 这样的一对圆括号,可以用"%(%s*%)" 其中的%s*可以匹配0到多个空格
    另一个示例是使用模式 "[_%a][_%w]*"来匹配lua中的标识符,标识符是一个由字母或下划线开始,伴随0到多个下划线、字母或数字的序列。
    修饰符"-""*" 一样,也是用于匹配0个或多个字符的。不过他会匹配最短的子串。虽然看似二者没什么差别但效果截然不同。如果使用"[_%a][_%w]- "来查找一个标识符时,他只会查找到第一个字母,因为"[_%w]-"总是匹配空串。假设要查找一个c程序中的注释,通常会首先尝试"/%*.*%/" 然后由于".*"会尽可能的扩展,因此程序中第一个"/*"只会与最后一个"*/"相匹配

    test="int x; /* x */ int y; /* y */"
    print(string.gsub(test,"/%*.*%*/","<COMMENT>"))
    --> int x;<COMMENT>
    

    但若使用 ".-"话就会变成这样

    test="int x; /* x */ int y; /* y */"
    print(string.gsub(test,"/%*.-%*/","<COMMENT>"))
    --> int x;<COMMENT> int y; <COMMENT>
    

    修饰符"?"用于匹配一个可选的字符。例如要在一段文本中寻找一个整数,而这个整数可以包括一个可选的正负号。那么适用模式"[+-]?%d+"就可以完成这项任任务。他可以匹配项
    "-12" "23" "+1000"这样的数字,而"[+-]"是一个匹配'+'号和'-'号的字符分类,后面的'?'说明可这个符号是可选的。与其他系统不同的是,Lua中的修饰符只能用用于一个字符分类,无法对一组分类进行修饰。无法写出一个匹配可选打次的模式。
    如果一个模式以一个'^'起始,那么他只会匹配目标字符串的开头部分。如果模式以'$'结尾,他只会匹配目标字符串的结尾部分。

    if string.find(s,"^%d")  then ...    -->检查一个字符串是否已数字开头
    
    if string.find(s,"^[+-]?%d+$")   then..  -->检查一个字符串是否表示一个整数,并且没有多余的前导字符和结尾字符。
    

    在模式中,还可以用"%b",用于匹配成对的字符。他的写法是"%b<x><y>" 其中<x>和<y>是两个不同的字符串,<x>作为一个起始字符,<y>是作为一个结束字符。例如模式"%b()"可匹配以'('开始,并以')'结束的子串s

    基础知识

    Lua中的stringc#中相同,string类型的值一旦改变,便要为新值开辟空间,并指向此空间。也就是说每次对string变量进行更改操作时返回的是一个新的值,下面的函数中就不再过多去说明了。

    1.基础字符串函数

    • string.rep(s,n)s:rep(n): 可以返回字符串重复n此的结果。例
    s="abc"
    print(s:rep(3))  -->abcabcabc
    
    • string.lower(s) 将所有大写转换为小写
    • string.upper(s)将所有小写转为大写
    • string.sub(s,i,j) 从字符串s中提取第i道第j个字符,还可以使用负数。-1代表倒数第一个字符,-2代表倒数第二个字符(从1开始)
    • string.char() 用于将输入的整数转换为对应的ASCII码表中的值,允许一个或多个参数如
    print(string.char(97))        -->
    print(string.char(98,99,100))  -->bcd
    
    • string.byte() 用途和string.char()相反,将对应的值转换为ASCII表中对应的数组
    print(string.btye("abc"))     -->97
    print(string,btye("abc"),3)  -->99 输出第三个字符的值,c ==> 99
    print(string,btye("abc"),-1)  -->99 输出最后一个字符的值,c ==> 99
    print(string.btye("abc"),1,-1)  -->97 98 99 输出从第一个到最后一个 
    
    • string.format() 格式化字符串和c语言中的print函数的规则基本相同
      %d:十进制 %x:十六进击 %o:八进制 %f浮点数 %s string 这里还可以在中间加入一些格式,如
    print(string.format("pi=%4f",math.pi))     -->3.14
    d=5;m=11;y=1990
    print(string.format("%02d/%0d/%04d",d,m,y))     -->05/11/1990
    

    其他还有很多这里只是简单地举几个例子。

    2.模式匹配函数

    Lua中由于考虑大小,没有支持正则表达式。而采用了自己的模式匹配。

    • 1. string.find函数

    string.find函数用于在一个给定的目标字符串中搜索一个模式。最简单的是搜索单词。如果赵傲这个单词,他就会返回单词的其实索引和结束所用,如果没找到则返回nil

    s="hello world"
    i,j=string.find(s,"hello")   
    print(i,j)         -->1,5
    print(string.sub(s,i,j))      --> hello
    print(string.find(s,"world"))    -->7 11
    i j=string.find("l")
    print(i,j)                  -->3  3
    print(string.find("s","lll"))    -->nil
    

    如果匹配成功,就可以用string,find的返回值结果来调用string.sub来提取出目标字符串中匹配于该模式的那部分子串。
    string.find还有一个可选的第三参数,他是一个索引,告诉函数应从目标字符串的那个位置开始搜索。

    • 2. string.math函数

    函数string.math和函数string.find在某种意义上很相似,它也是用一个在字符串中搜索的一种模式。不同的是,string.math返回的是目标字符串中模式匹配的那部分子串,而并非位置。
    对于固定的模式,该函数可能没有什么意义例如"hello"。但当使用变量模式是,它的特性就显现出来了。

    date="today is 17//1990"
    d=string.math(date,"%d+/%d+/%d+")      -->这里具体含义之后再具体讲解
    print(d)    17/7/1990
    
    • 3. string.gsub函数

    string.gusb函数有3个参数:目标字符串、模式、替换字符串 作用就是将所有出现该模式的地方替换为替换字符串

    s=string.gsub("lua is cute","cute","great" )
    print(s)                              -->lua is great
    s=string.gsub("all lii","l","x")
    print(s)                        -->axx xii
    string=string,gsub("lua is great","Sol","Sun")
    print(s)          -->lua is great
    

    另外还有可选的第四个参数,可以限制替换的次数

    s=string.gsub("all lii","l","x",1)
    print(s)              --> axl lii
    s=string.gsub("all lii","l","x",2)
    print(s)              -->axx lii
    

    函数是string.gsub还有一种结果,即实际替换的次数,例如下面就是一种统计字符串中空格数量的简单方法

    s="this is a lua string"
    count=select(2,string.gsub(s," "," "))    ==>s,count=string.gsub(s," "," ")  
    
    • 4. string.gmatch函数

    string.gmatch会返回一个函数。通过这个函数可以遍历到一个字符串中所有出现指定摸式的地方。

    words={}
    for w in string.gamtch(s,"%a+") do
      words[#words+1]=w
    end
    

    其中模式"%a+"表示匹配一个或多个字母字符的序列(也就是单词),这里会遍历其中所有的单词,并存入其中。在模式中"点"具有特殊的意义,因此若要表示一个点必须写为"%."

    3 模式

    介意用字符分类创建更多有用的模式。字符分类就是模式中的一项。可以与一个热顶级和中的任意字符相匹配。例如分类"%d"可匹配任意数字。例如可以用
    "%d%d/%d%d/%d%d%d%d" 来搜索符合"dd/mm/yyyy"格式的日期

    s="deadline is 30/05/1999,firm"
    date="%d%d/%d%d/%d%d%d%d"
    print(string.sub(s,string.find(s,data)))      -->30/05/1999
    

    下面是所有的字符分类

    字符 意义
    . 所有字符
    %a 字母
    %c 控制字符
    %d 数字
    %l 小写字母
    %p 标点符号
    %s 空白字符
    %u 大写字母
    %w 字母和数字字符
    %x 十六进制数字
    %z 内部表示为0的字符

    这些分类的大写行使表示他们的补集,例如"%A"表示所有非字母字符

    print(string.sub("hello, up-down!","%A",".'))   
     -->hello..up.down.  4 返回两个值一个是替换之后的string 一个是替换的次数
    

    在模式里,还有一些字符串被称为“魔法字符”他们有着特殊的含义。这些魔法字符有
    { } . % + - * ? [ ] ^ $
    字符串%作为这些魔法字符的转义符,例如"%."表示匹配一个点 "%%"表示匹配字符"%"不仅可以把"%"用于魔法字符,还可以用于其他所有非字母数字的字符。当不确定某个字符是不是需要被转义是,应该直接前置一个转义符。
    对于lua来说,模式就是普通的字符串。并想起他字符串一样遵循相同的规则。只有模式函数才会解释它们,此时参会将"%"当做转义符来处理。
    在一堆放括号内将不同的字符分类或者单个字符组合起来,即可创造出属于用户自己的字符分类,这种新的字符分类叫做字符集(char-set)。例如,字符集["%w_"]表示同时匹配字母、数字和下划线。字符集[01]表示匹配二进制数字 字符集[%[%]]表示匹配方括号本身。如果需要统计一段文本中元音的数量,可以这么写

    nvow=select(2,string.gsub(text,"[AEIOUaeiou]",""))
    

    在字符集中表示一段字符范围的做法是写出自付范围的第一个字符和最后一个字符并用横线连接它们,但这种形式用的较少因为大部分常用的字符范围都已经预定义好了。如[0-9]即为%d
    [0-9a-fA-F]则为"%x"不过如果需要查找一个8进制的数字,那么可以写[0-7]而不是[01234567]。在一个字符集前加一个'^'即可表示这个字符集的补集。例如[^0-7]表示所有非八进制数字的字符。而模式[^\n]则表示了除了换行符之外的其他字符。对于简单地分类,使用大写形式也可以得到他的补集,"%S"显然比[^%s]简答
    也可以通过修饰符来藐视模式中的重复可选部分。lua提供四种修饰符

    修饰符 意义
    + 重复1次或多次
    * 重复0次或多次
    - 也是重复0次或多次
    ? 可选部分(出现0或1次)

    “+”修饰符科普配属于字符串分类的一个或多个字符。他总是获取与模式相匹配的最长序列,模式"%a+" 表示一个或多个字母,即单词:

    print(string.gsub("one, and two ;and three","&a+","word"))
    -->word, word word; word word  (将所有单词换成 word)
    

    模式"%d+" 匹配一个或多个数组(一个整数)

    print(string.math("the number 1298 is even","%d+"))     -->1298
    

    修饰符 "*" 类似于"+",但它还接受出现0次的情况。一种典型用途是匹配一个模式不同部分之间的空格。 比如说像匹配() 或者( )这样的一对圆括号,可以用"%(%s*%)"其中的%s*可以匹配0到多个空格
    另一个示例是使用模式"[_%a][_%w]*"来匹配lua中的标识符,标识符是一个由字母或下划线开始,伴随0到多个下划线、字母或数字的序列。
    修饰符"-""*" 一样,也是用于匹配0个或多个字符的。不过他会匹配最短的子串。虽然看似二者没什么差别但效果截然不同。如果使用"[_%a][_%w]- "来查找一个标识符时,他只会查找到第一个字母,因为"[_%w]-"总是匹配空串。假设要查找一个c程序中的注释,通常会首先尝试 "/%*.*%/" 然后由于".*"会尽可能的扩展,因此程序中第一个"/*"只会与最后一个"*/"相匹配

    test="int x; /* x */ int y; /* y */"
    print(string.gsub(test,"/%*.*%*/","<COMMENT>"))
    --> int x;<COMMENT>
    

    但若使用 ".-"话就会变成这样

    test="int x; /* x */ int y; /* y */"
    print(string.gsub(test,"/%*.-%*/","<COMMENT>"))
    --> int x;<COMMENT> int y; <COMMENT>
    

    修饰符"?"用于匹配一个可选的字符。例如要在一段文本中寻找一个整数,而这个整数可以包括一个可选的正负号。那么适用模式"[+-]?%d+"就可以完成这项任任务。他可以匹配项
    "-12" "23" "+1000"这样的数字,而"[+-]"是一个匹配'+'号和'-'号的字符分类,后面的'?'说明可这个符号是可选的。与其他系统不同的是,Lua中的修饰符只能用用于一个字符分类,无法对一组分类进行修饰。无法写出一个匹配可选打次的模式。
    如果一个模式以一个'^'起始,那么他只会匹配目标字符串的开头部分。如果模式以'$'结尾,他只会匹配目标字符串的结尾部分。

    if string.find(s,"^%d")  then ...    -->检查一个字符串是否已数字开头
    
    if string.find(s,"^[+-]?%d+$")   then..  -->检查一个字符串是否表示一个整数,并且没有多余的前导字符和结尾字符。
    

    在模式中,还可以用"%b",用于匹配成对的字符。他的写法是"%b<x><y>" 其中<x><y>是两个不同的字符串,<x>作为一个起始字符,<y>是作为一个结束字符。例如模式"%b()"可匹配以'('开始,并以')'结束的子串
    s="a (enclosed (in) parenthesses) line"
    print(string.gsub(s,"%d()","") -->a line

    这种模式的典型用法包括"%b()" "%b[]" "%b{}" "%b<>"


    4. 捕获

    捕获功能可根据一个模式从目标字符串中抽出匹配与该模式的内容。在指定捕获时,应将模式中需要捕获的部分写到一对圆括号内。

    pair="name = Anna"
    key,value=string.match(pair, " (%a+) %s*=%s* (%a+) ")
    print(key,value)    --> name Anna
    

    这里括号中的值为匹配两个单词,括号外是首先匹配空格然后匹配等号继续匹配空格。并且会把表达式中用()括起来的值返回。

    date="today is 17/7/1990"
    d,m,y=string.match(date,"(%d+)%/(%d+)%/(%d+)")
    print(d,m,y)   -->         17     7    1990    
    

    相关文章

      网友评论

          本文标题:lua入门笔记7 字符串库

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