分类:
2013-01-24 11:04:08
原文地址:参考手册 - 5.4 - 字符串操作 作者:hshq_cn
该库为字符串操作提供常规函数,例如查找和抽取子串以及模式匹配。在Lua中索引字符串时,第一个字符在位置1(不像C是在0处)。索引允许为负数,被解释为从字符串末尾往回索引。因此,最后一个字符在-1位置,依此类推。
字符串库在表内提供所有函数。它也给字符串设置元表,其中的__index
字段指向string
表。因此,你可以使用面向对象风格的字符串函数。例如,string.byte(s, i)
可写为s:byte(i)
。
s[i]
, s[i+1]
, ···, s[j]
的内部数字代码。i
缺省为1;j
缺省为i
。
注意数字代码不一定是跨平台可移植的。
注意数字代码不一定是跨平台可移植的。
返回给定函数的二进制表示的字符串,之后在其上应用返回函数的拷贝。function
必须是不带upvalueLua函数。
s
中查找pattern
的第一个匹配。如果找到则返回它开始和结束处在s
中的索引;否则,返回nil。可选的第三参数init
是数字,指定从哪儿开始搜索;其缺省值是1并且可为负数。如果真值作为可选的第四参数plain
,则关闭模式匹配设备,所以函数执行无格式的“查找子串”操作,pattern
中的字符并不被认为是“魔术的(magic)”。注意,如果给出了plain
,则init
也必须给出。
如果模式具有捕获(capture),则在成功的匹配中被捕获的值也在两个索引后面返回。
printf
族标准C函数同样的规则。仅有的区别是不支持*
、l
、L
、n
、p
和h
等选项/修饰符,而且有个额外选项q
。q
选项以可安全地为Lua解释器读取的适当形式格式化字符串:字符串被写在双引号之间,而且字符串中的所有双引号、换行、内嵌的0和反斜杠被恰当地转义。例如,调用
string.format('%q', 'a string with "quotes" and \n new line')
产生字符串:
"a string with \"quotes\" and \
new line"
选项c
、d
、E
、e
、f
,
g
、G
、i
、o
、u
、X
和x
都预期得到数字作为参数,然而q
和s
期望得到字符串。
该函数不接受含有内嵌的0的字符串值,除了作为q
选项的参数。
pattern
的下一个捕获,从字符串s
开头直到结尾。如果pattern
没指定捕获则每次调用产生整个匹配。
作为例子,下面的循环
s = "hello world from Lua"
for w in string.gmatch(s, "%a+") do
print(w)
end
将迭代来自字符串s
的所有单词,每行打印一个。下一个例子从给定的字符串收集所有的键=值
对放在表中:
t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "^(%w+)=(%w+)") do
t[k] = v
end
对于该函数,模式起始处的‘^
’不能作为锚点,因为这会阻止迭代。
s
的拷贝,其中出现的所有(或前n
个,如果指定)pattern
被替换为repl
——可以是字符串、表或函数,指定的替换串。gsub
也返回出现的匹配的总数作为第二个值。
如果repl
是字符串,它的值被用作替换式。字符%
用作转义字符:repl
中的任何形如%n
的序列代表第n个捕获的子串(见下面),其中n在1和9之间。序列%0
代表整个匹配。序列%%
代表单个%
。
如果repl
是表,则对于每个匹配,用第一个捕获作为键查询表;如果模式未指定捕获,则整个匹配被用作键。
如果repl
是函数,则每次匹配发生时都按顺序传入所有捕获的子串作为参数调用该函数;如果模式没指定捕获,则整个匹配作为单个参数传入。
如果表查询或函数调用返回的结果是个字符串或数字,则被用作替换串;否则,如果是false或nil,则不发生替换(即原始匹配被保持在字符串中)。
这里有一些例子:
x = string.gsub("hello world", "(%w+)", "%1 %1")
--> x="hello hello world world"
x = string.gsub("hello world", "%w+", "%0 %0", 1)
--> x="hello hello world"
x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
--> x="world hello Lua from"
x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
--> x="home = /home/roberto, user = roberto"
x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
return loadstring(s)()
end)
--> x="4+5 = 9"
local t = {name="lua", version="5.1"}
x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
--> x="lua-5.1.tar.gz"
""
长度为0。内嵌的0被计算在内,所以"a\000bc\000"
长度为5。
s
中查找pattern
的首次匹配。如果找到一个,则返回来自模式的捕获;否则返回nil。如果pattern
未指定捕获则返回整个匹配。可选的第三个参数init
是数字,指定从哪儿开始搜索;其缺省值是1并且可为负。
s
的n
个拷贝拼接字符串。
s
的颠倒的字符串。
s
的子串,它起始于i
并延续到j
;i
和j
可为负数。如果省略j
,则它被假定为-1(同字符串长度一样)。特别地,调用string.sub(s,1,j)
返回s
长为j
的前缀,而且string.sub(s, -i)
返回s
长为i
的后缀。
一个字符类被用于表示一组字符。允许用下面的组合描述字符类:
^$()%.[]*+-?
中的一个)表示字符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
。
模式项可能为
*
’的单个字符类,它匹配该类中的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()
匹配带有平衡的圆括号的表达式。
模式是一系列的模式项。在模式开头的‘^
’将匹配固定在源串的开头。 在模式结尾的‘$
’将匹配固定在源串的结尾。在其他位置上,‘^
’和‘$
’没有特殊含义,表示它们自身。
模式可以含有括在圆括号内的子模式;它们描述捕获。当成功进行一个匹配,源串中匹配捕获的子串被存储(捕获)以便将来使用。捕获根据它们的左圆括号进行编号。例如,在模式"(a*(.)%w(%s*))"
中,字符串的匹配"a*(.)%w(%s*)"
的部分作为第一个捕获被存储(因此被编号为1);匹配“.
”的字符被捕获并编号为2,匹配“%s*
”的部分被编号为3。
作为一种特殊情况,空捕获()
捕获当前字符串位置(一个数字)。例如,如果我们把模式"()aa()"
用于字符串"flaaap"
,将有两个捕获:3和5。
模式不能含有内嵌的0。使用%z
代替。