Lua中的string库和强大的模式匹配学习笔记
lua原生解释器对字符串的处理能力是十分有限的,强大的字符串操作能力来自于string库。lua的string函数导出在stringmodule中。在lua5.1,同时也作为string类型的成员方法,因此,我们既可以写成string.upper(s),也可以s:upper(),选择你喜欢的写法。
string.len(s)返回s的长度。
string.rep(s,n)返回重复s字符串n次的字符串。
string.lower(s)返回一份已将大写转成小写的字符串s的拷贝
lower,upper都是使用本地字符集的,另外,如果你想对一个string数组进行排序,并不区分大小写,你可能像这么写:
table.sort(a,function(a,b) returnstring.lower(a)<string.lower(b) end)
string.sub(s,i,j)将从s提取一段字符串,从i到j(闭区间[i,j]),当然你可以使用负索引值,将从字符串尾部算起,-1是最后一个字符,-2是倒数第二,等等,这么做的好处是当我们要提取直到末尾几个字符时,从后面数起就很方便。例如:
s="[hello,world]" print(string.sub(s,2,-2))-->hello,world
记住,lua中的字符串是不可变的。
string.char,string.byte用于转换字符和对于的数字之间值。例如:
i=97 print(string.char(i,i+1,i+2))-->abc print(string.byte("abc")) -->97 print(string.byte("abc"),-2) -->98
lua5.1string.byte可以接受第三个参数,返回i,j之间的多个值。例如,这么写将字符串转成字符值数组:
t={s.byte(1,-1}
要想重新转成字符串的话:
string.char(unpack(t))
string.format是强大字符串格式化函数,和c语言的printf类似,这里不累述。
luastring库里最强大的函数是那些模式匹配函数:find,match,gsub,gmatch。和其他脚本语言不同,lua既没有用POSIX的正则表达式,也没有用perl的正则表达式。原因是实现这些导致lua占用更多内存,而lua的初衷是小巧的,嵌入应用的语言。lua用少于500行的代码实现了自己的一套模式匹配,虽然不如标准的正则表达式强(一般需要4000以上代码),但也足够强大。
string.find将查找目标模板在给定字符串中出现的位置,找到返回起始和结束位置,没找到返回nil。例如:
s="hello,world" i,j=string.find(s,"hello") print(string.sub(s,i,j))
当然,string.find还可以给定起始搜索位置,当你想找出所有出现的位置时,这个参数就很有用,例如想知道换行符出现在那些地方:
localt={} locali=0 whiletruedo i=string.find(s,"\n",i+1) ifi==nilthenbreakend t[#t+1]=i end
string.match和string.find类似,都是在指定的string中查找相应的模式。不同的是,他返回的是找到的那部分string:
print(string.match("hello,world","hello"))-->hello
对于像"hello"这样的固定模式来说,这个函数就没啥意义了。但是对于可变模式来说,就显示出他的强大威力了:
date="nowis2014/10/617:58" d=string.match(date,"%d+/%d+/%d+") print(d) -->2014/10/6
string.gsub有三个参数,给定字符串,匹配模式和替代字符串。作用就是将所有符合匹配模式的地方都替换成替代字符串。并返回替换后的字符串,以及替换次数。
s=string.gsub("Luaiscute","cute","great") print(s)-->Luaisgreat
string.gmatch函数将返回一个迭代器,用于迭代所有出现在给定字符串中的匹配字符串。
模式:
字符类:(characterclasses)
.allcharacters %aletters %ccontrolcharacters %ddigits %llower-caseletters %ppunctuationcharacters %sspacecharacters %uupper-caseletters %walphanumericcharacters %xhexadecimaldigits %zthecharacterwhoserepresentationis0
他们的大写版本是他本身的互补。
魔法字符:
().%+-*?[]^$
用%进行转义。'%%'代表'%'
字符集(char-set):使用字符集可以自定义字符类。
1.不同的字符类,和单字符之间用[]
[%w_]匹配字母数字字符和下划线。
[01]匹配二进制数
2.要想字符集内包含字符区间,起止之间加上-
[0-9]相当于%d
[0-9a-fA-F]相当于%x
3.如果想得到该字符集的互补,前面加上^
[^0-7]任何非八进制数字
重复或可选修饰符
+1ormorerepetitions,匹配最长的, *0ormorerepetitions 最长的 -also0ormorerepetitions最短的 ?optional(0or1occurrence)
捕获
捕获机制允许一个模式串中的一部分来匹配目标串种的一部分。写法是模式串中你需要捕获的那部分用()括起来,例如:
pair="name=anna" key,value=string.match(pair,"(%a+)%s*=%s*(%a+)") print(key,value)-->nameanna
我们也可以将捕获用于模式串自身,"([\"'])(.-)%1",这里的%1表示匹配第一个捕获的一份拷贝。
替换
前面已知道,string.gsub的参数可以是string,其实,也可以是个函数,或是table,如果是函数,就会用捕获的内容作为参数调用该函数,将返回的内容作为替换字符串。如果是table,则用捕获的内容为key去取table的值来作为替换字符串,如果不存在,就不做替换。如:
functionexpand(s) returnstring.gsub(s,"$(%w+)",_G) end name="Lua";status="great" print(expand("$nameis$status,isn'tit?"))
(完)