end
end
测试功能如下:
>table.sort(guild,sortLevelNameAsc)
>foridx,valueinipairs(guild)doprint(idx,value.name)end
1,Mallaithe
2,Cladhaire
3,Sagart
table.foreachi(table,function(i,v))
会期望一个从1(数字1)开始的连续整数范围,遍历table中的key和value逐对进行function(i,v)操作
t1={2,4,6,language="Lua",version="5",8,10,12,web="hellolua"};
table.foreachi(t1,function(i,v)print(i,v)end);--等价于foreachi(t1,print)
输出结果:
12
24
36
48
510
612
table.foreach(table,function(i,v))
与foreachi不同的是,foreach会对整个表进行迭代
t1={2,4,6,language="Lua",version="5",8,10,12,web="hellolua"};
table.foreach(t1,function(i,v)print(i,v)end);
输出结果:
12
24
36
48
510
612
webhellolua
languageLua
version5
table.getn(table)
返回table中元素的个数
t1={1,2,3,5};
print(getn(t1))
->4
table.setn(table,nSize)
设置table中的元素个数
5.4-字符串操作
该库为字符串操作提供常规函数,例如查找和抽取子串以及模式匹配。
在Lua中索引字符串时,第一个字符在位置1(不像C是在0处)。
索引允许为负数,被解释为从字符串末尾往回索引。
因此,最后一个字符在-1位置,依此类推。
字符串库在表string内提供所有函数。
它也给字符串设置元表,其中的__index字段指向string表。
因此,你可以使用面向对象风格的字符串函数。
例如,string.byte(s,i)可写为s:
byte(i)。
string.byte(s[,i[,j]])
返回字符s,s[i+1],···,s[j]的内部数字代码。
i缺省为1;j缺省为i。
注意数字代码不一定是跨平台可移植的。
string.char(···)
接受0获多个整数。
返回一个字符串,其长度等于参数个数,其中的每个字符的内部数字代码等于相应的参数。
注意数字代码不一定是跨平台可移植的。
string.dump(function)
返回给定函数的二进制表示的字符串,之后在其上应用loadstring返回函数的拷贝。
function必须是不带upvalueLua函数。
string.find(s,pattern[,init[,plain]])
在字符串s中查找pattern的第一个匹配。
如果找到则返回它开始和结束处在s中的索引;否则,返回nil。
可选的第三参数init是数字,指定从哪儿开始搜索;其缺省值是1并且可为负数。
如果真值作为可选的第四参数plain,则关闭模式匹配设备,所以函数执行无格式的“查找子串”操作,pattern中的字符并不被认为是“魔术的(magic)”。
注意,如果给出了plain,则init也必须给出。
如果模式具有捕获(capture),则在成功的匹配中被捕获的值也在两个索引后面返回。
string.format(formatstring,···)
Returnsaformattedversionofitsvariablenumberofargumentsfollowingthedescriptiongiveninitsfirstargument(whichmustbeastring).格式字符串遵循同printf族标准C函数同样的规则。
仅有的区别是不支持*、l、L、n、p和h等选项/修饰符,而且有个额外选项q。
q选项以可安全地为Lua解释器读取的适当形式格式化字符串:
字符串被写在双引号之间,而且字符串中的所有双引号、换行、内嵌的0和反斜杠被恰当地转义。
例如,调用
string.format('%q','astringwith"quotes"and\nnewline')
产生字符串:
"astringwith\"quotes\"and\
newline"
选项c、d、E、e、f,g、G、i、o、u、X和x都预期得到数字作为参数,然而q和s期望得到字符串。
该函数不接受含有内嵌的0的字符串值,除了作为q选项的参数。
string.gmatch(s,pattern)
返回一个迭代器函数,每次调用返回来自pattern的下一个捕获,从字符串s开头直到结尾。
如果pattern没指定捕获则每次调用产生整个匹配。
作为例子,下面的循环
s="helloworldfromLua"
forwinstring.gmatch(s,"%a+")do
print(w)
end
将迭代来自字符串s的所有单词,每行打印一个。
下一个例子从给定的字符串收集所有的键=值对放在表中:
t={}
s="from=world,to=Lua"
fork,vinstring.gmatch(s,"^(%w+)=(%w+)")do
t[k]=v
end
对于该函数,模式起始处的‘^’不能作为锚点,因为这会阻止迭代。
string.gsub(s,pattern,repl[,n])
返回s的拷贝,其中出现的所有(或前n个,如果指定)pattern被替换为repl——可以是字符串、表或函数,指定的替换串。
gsub也返回出现的匹配的总数作为第二个值。
如果repl是字符串,它的值被用作替换式。
字符%用作转义字符:
repl中的任何形如%n的序列代表第n个捕获的子串(见下面),其中n在1和9之间。
序列%0代表整个匹配。
序列%%代表单个%。
如果repl是表,则对于每个匹配,用第一个捕获作为键查询表;如果模式未指定捕获,则整个匹配被用作键。
如果repl是函数,则每次匹配发生时都按顺序传入所有捕获的子串作为参数调用该函数;如果模式没指定捕获,则整个匹配作为单个参数传入。
如果表查询或函数调用返回的结果是个字符串或数字,则被用作替换串;否则,如果是false或nil,则不发生替换(即原始匹配被保持在字符串中)。
这里有一些例子:
x=string.gsub("helloworld","(%w+)","%1%1")
-->x="hellohelloworldworld"
x=string.gsub("helloworld","%w+","%0%0",1)
-->x="hellohelloworld"
x=string.gsub("helloworldfromLua","(%w+)%s*(%w+)","%2%1")
-->x="worldhelloLuafrom"
x=string.gsub("home=$HOME,user=$USER","%$(%w+)",os.getenv)
-->x="home=/home/roberto,user=roberto"
x=string.gsub("4+5=$return4+5$","%$(.-)%$",function(s)
returnloadstring(s)()
end)
-->x="4+5=9"
localt={name="lua",version="5.1"}
x=string.gsub("$name-$version.tar.gz","%$(%w+)",t)
-->x="lua-5.1.tar.gz"
string.len(s)
接受字符串并返回其长度。
空串""长度为0。
内嵌的0被计算在内,所以"a\000bc\000"长度为5。
string.lower(s)
接受字符串并返回其所有大写字母变为小写的拷贝。
所有其他字符不变。
大写字母的定义依赖于但前locale。
string.match(s,pattern[,init])
在字符串s中查找pattern的首次匹配。
如果找到一个,则返回来自模式的捕获;否则返回nil。
如果pattern未指定捕获则返回整个匹配。
可选的第三个参数init是数字,指定从哪儿开始搜索;其缺省值是1并且可为负。
string.rep(s,n)
返回字符串s的n个拷贝拼接字符串。
string.reverse(s)
返回字符串s的颠倒的字符串。
string.sub(s,i[,j])
返回s的子串,它起始于i并延续到j;i和j可为负数。
如果省略j,则它被假定为-1(同字符串长度一样)。
特别地,调用string.sub(s,1,j)返回s长为j的前缀,而且string.sub(s,-i)返回s长为i的后缀。
string.upper(s)
接受字符串并返回其所有小写字母变为大写的拷贝。
所有其他字符不变。
小写字母的定义依赖于但前locale。
5.4.1-模式
字符类(CharacterClass):
一个字符类被用于表示一组字符。
允许用下面的组合描述字符类:
*x:
(此处x不是魔术字符^$()%.[]*+-?
中的一个)表示字符x本身。
*.:
(一个点)表示所有字符。
*%a:
表示所有字母。
*%c:
表示所有控制字符。
*%d:
表示所有十进制数字。
*%l:
表示所有小写字母。
*%p:
表示所有标点符号。
*%s:
表示所有空白字符。
*%u:
表示所有大写字母。
*%w:
表示所有字母数字字符。
*%x:
表示所有十六进制数字。
*%z:
表示0值字符。
*%x:
(此处x是任何非字母数字字符)表示字符x。
这是转义魔术字符的标准方式。
当被用于在模式中表示自身时,任何标点符号(甚至非魔术的)都能前缀一个‘%’。
*[set]:
表示set中的所有字符的联合构成的分类。
通过用‘-’分隔截止字符可以指定某个范围的字符。
上面描述的所有种类的%x都可用作set的部件。
set中的所有其他字符表示它们自身。
例如[%w_](或[_%w])表示所有字母数字字符和下划线,[0-7]表示八进制数字,[0-7%l%-]表示八进制数字和小写字母以及‘-’字符。
字符范围和字符类之间的相互作用是未定义的。
因此类似[%a-z]或[a-%%]的模式没有意义。
*[^set]:
表示set的补集,其中的set在上面解释了。
所有单字母表示的字符类(%a、%c,等等),相应的大写字母表示该字符类的补集。
例如,%S表示所有非空白符。
字母、空白和其他字符组合的定义依赖于当前locale。
特别地,字符类[a-z]可能不等于%l。
模式项(PatternItem):
模式项可能为
*单个字符类,它匹配该类中的任意单个字符;
*后跟‘*’的单个字符类,它匹配该类中的0或多个字符。
这些重复项将总是匹配最长的可能序列;
*后跟‘+’的单个字符类,它匹配该类中的1或多个字符。
这些重复项将总是匹配最长的可能序列;
*后跟‘-’的单个字符类,它也匹配该类中的0或多个字符。
与‘*’不同,这些重复项将总是匹配最短的可能序列;
*后跟‘?
’的单个字符类,它匹配出现0或1次该类中的字符;
*%n,其中n在1和9之间;这种项匹配一个等价于捕获的字符串的第n个子串(见下面);
*%bxy其中x和y是两个不同的字符;这种项匹配始于x终于y的字符串,并且x和y是对称的。
这表示,如果一个人从左到右读字符串,对x计数为+1,对y计数为-1,结尾的y是第一个遇到计数为0的y。
例如,项%b()匹配带有平衡的圆括号的表达式。
模式(Pattern):
模式是一系列的模式项。
在模式开头的‘^’将匹配固定在源串的开头。
在模式结尾的‘$’将匹配固定在源串的结尾。
在其他位置上,‘^’和‘$’没有特殊含义,表示它们自身。
捕获(Captures):
模式可以含有括在圆括号内的子模式;它们描述捕获。
当成功进行一个匹配,源串中匹配捕获的子串被存储(捕获)以便将来使用。
捕获根据它们的左圆括号进行编号。
例如,在模式"(a*(.)%w(%s*))"中,字符串的匹配"a*(.)%w(%s*)"的部分作为第一个捕获被存储(因此被编号为1);匹配“.”的字符被捕获并编号为2,匹配“%s*”的部分被编号为3。
作为一种特殊情况,空捕获()捕获当前字符串位置(一个数字)。
例如,如果我们把模式"()aa()"用于字符串"flaaap",将有两个捕获:
3和5。
模式不能含有内嵌的0。
使用%z代替。
Lua模式匹配---主要注意其字符部分
模式匹配函数
在string库中功能最强大的函数是:
string.find(字符串查找)
string.gsub(全局字符串替换)
string.gfind(全局字符串查找)
string.gmatch(返回查找到字符串的迭代器)
这些函数都是基于模式匹配的。
与其他脚本语言不同的是,Lua并不使用POSIX规范的正则表达式[4](也写作regexp)来进行模式匹配。
主要的原因出于程序大小方面的考虑:
实现一个典型的符合POSIX标准的regexp大概需要4000行代码,这比整个Lua标准库加在一起都大。
权衡之下,Lua中的模式匹配的实现只用了500行代码,当然这意味着不可能实现POSIX所规范的所有更能。
然而,Lua中的模式匹配功能是很强大的,并且包含了一些使用标准POSIX模式匹配不容易实现的功能。
string.gmatch(str,pattern)
这是一个返回迭代器的函数.实际的用例如下:
s="helloworldfromLua"
forwinstring.gmatch(s,"%a+")do
print(w)
end
这里是一个捕获并将配对字符分别存到不同变量的例子:
t={}
s="from=world,to=Lua"
fork,vinstring.gmatch(s,"(%w+)=(%w+)")do
t[k]=v
end
fork,vinpairs(t)do
print(k,v)
end
string.gsub(str,pattern,repl,n)
string.gsub()函数根据给定的配对表达式对源字符串str进行配对,同时返回源字符串的一个副本,该副本中成功配对的所有子字符串都将被替换.函数还将返回成功配对的次数.实际的替换行为由repl参数的类型决定:
当repl为字符串时,所有成功配对的子字符串均会被替换成指定的repl字串.
当repl为table时,对每个成功配对的子字符串,函数均会试图寻找以其为key值的table中的元素,并返回该元素.如果该配对包含任何捕获信息,则以编号为1号的捕获作为key值进行查找.
当repl为函数时,每个成功配对的子字符串均会作为参数被传入到该函数中去.
在repl是table或函数时,如果该table或函数返回了字串或数字的值,这个值依然会被用于替换副本字串中的配对子字串.如果该table/函数返回的值为空,将不发生替换.
n参数可选,当它被指定时,string.gsub()函数只对源字符串中的前n个成功配对的成员进行操作.
以下是几个例子:
>print(string.gsub("helloworld","(%w+)","%1%1"))
hellohelloworldworld2
>print(string.gsub("helloLua","(%w+)%s*(%w+)","%2%1"))
Luahello1
>string.gsub("helloworld","%w+",print)
helloworld2
>lookupTable={["hello"]="hola",["world"]="mundo"}
>print(string.gsub("helloworld","(%w+)",lookupTable))
holamundo2
string.match(st