快速掌握Lua 5.3 —— 字符串库 (1)
2016-02-20 00:27
274 查看
Q:对字符串操作的基本函数?
A:[code]--[[ string.byte(s [, i [, j]]) 依次返回字符串"s"中从"i"到"j"的字符的ASCII码。 "i"默认为1,"j"默认为"i"。"i"或"j"如果为负数,则在字符串"s"中从后往前数。]] print(string.byte("abc")) --> 97 print(string.byte("abc", 2)) --> 98 print(string.byte("abc", 2, 3)) --> 98 99 print(string.byte("abc", -1)) --> 99 --[[ string.char(···) 与"string.byte()"功能相反,将ASCII码转换为字符。]] print(string.char(97)) --> a print(string.char(97, 98, 99)) --> abc --[[ string.dump(function [, strip]) 返回一个字符串,字符串是函数"function"被转换为二进制流的内容。 方便函数的序列化,序列化后的函数可以被传递。 如果"strip"为真,则二进制流中不携带函数的调试信息(局部变量名,行号,等等。)]] function foo() print("Hello World!") end s = string.dump(foo) -- 函数"foo"被转换为二进制流存储在变量"s"中。 f = load(s) -- 将字符串中的二进制流转换为函数。"f"相当于"foo"的复本。 f() -- Hello World! -- 相当于调用了"foo()"。 --[[ string.len(s) 返回字符串"s"的长度。内嵌的'\0'也会被统计。]] print(string.len("abc")) --> 3 print(string.len("a\000b\000c")) --> 5 --[[ string.lower(s) 将字符串中所有大写子母转换为小写。 string.upper(s) 将字符串中所有小写子母转换为大写。]] print(string.lower("aBc$e*f")) --> abc$e*f print(string.upper("abc$e*f")) --> ABC$E*F --[[ string.rep(s, n [, sep]) 返回重复"n"次,以"sep"为分隔符的字符串。"sep"默认为空字符串。]] print(string.rep("ab", 3)) --> ababab print(string.rep("ab", 3, "&*")) --> ab&*ab&*ab --[[ string.reverse(s) 返回字符串"s"的倒序排列。]] print(string.reverse("abc")) --> cba --[[ string.sub(s, i [, j]) 返回字符串"s"中从第"i"个字符到第"j"个字符的子串。 "i"或"j"如果为负数,则在字符串"s"中从后往前数。 "j"默认为-1,即字符串最后一个字符。]] print(string.sub("abc", 2)) --> "bc" print(string.sub("abc", 1, -2)) --> "ab" --[[ string.format(formatstring, ···) 功能类似于C语言中的"sprintf()"。"formatstring"是格式化字符串, 规则遵循C语言中的格式化字符串规则,除了不支持"*, h, L, l, n,"。 额外支持"q",可以处理转义字符。]] print(string.format("pi = %.4f", math.pi)) --> pi = 3.1416 d = 5; m = 11; y = 1990 print(string.format("%02d/%02d/%04d", d, m, y)) --> 05/11/1990 tag, title = "h1", "a title" print(string.format("<%s>%s</%s>", tag, title, tag)) --> <h1>a title</h1> print(string.format('%q', 'a string with "quotes" and \n new line')) --[[ result: 第一行末尾的'\'是多行字符串的换行符。 "a string with \"quotes\" and \ new line"]]
Q:什么是”magic characters”?
A:在”pattern”中使用,具有特殊含义的字符。[code].: (一个点)表示任何一个字符。 +: 匹配一次或多次,最长匹配。 *: 匹配零次或多次,最长匹配。 -: 匹配零次或多次,最短匹配。 ?: 匹配零次或一次。 []: 两个字符组合使用表示一个字符集合。 (): 两个字符组合使用表示一个捕获。 ^: 表示从行首开始匹配。 $: 表示匹配到行尾。 %: 转义字符。可以将"magic characters"转义为其字面的含义。
Q:什么是”Character Class”?
A:在”pattern”中使用,可以匹配一个特定字符集合内任何字符的模式项。[code]x:(这里'x'不能是"magic characters"中的一员)表示字符'x'自身。 %a: 表示任何字母。 %c: 表示任何控制字符。 %d: 表示任何数字。 %g: 表示任何除空格符外的可打印字符。 %l: 表示所有小写字母。 %p: 表示所有标点符号。 %s: 表示空格符。 %u: 表示所有大写字母。 %w: 表示所有字母及数字。 %x: 表示所有十六进制数字符号。 %x: '%'是转义字符,'x'是任意非字母或数字的字符,"%x"表示字符'x'本身。 '%'是对"magic characters"转义的标准方法。 [set]: 表示一个字符的集合"set"。 可以使用'-'字符以升序的方式连接两个字符以表示一个范围内的所有字符, 也可以单独列出需要的字符以组成一个字符的集合。 例如,"[%w_]"(或"[_%w]")表示所有的字母数字加下划线的字符集合, "[0-7]"表示八进制数字的字符集合, "[0-7%l%-]"表示八进制数字加小写字母加'-'字符的字符集合。 [^set]: 表示一个字符的集合"set"的补集,其中"set"如上面的解释。 上面从"%a"到第一个"%x"的这些模式项,若将其字母改为大写,均表示其对应的补集。 例如,"%S"表示所有非空格字符的字符。
Q:什么是最短匹配与最长匹配?
A:根据”pattern”,匹配尽可能多的字符是最长匹配,反之为最短匹配。以C语言中匹配注释的实例进行说明,实例最直观,
[code]code = "int x; /* x */ int y; /* y */" -- "string.gsub()"将匹配到的字符串替换为指定字符串。 print(string.gsub(test, "/%*.*%*/", "<COMMENT>")) --> int x; <COMMENT> --[[ '*'使用最长匹配,直到找到最后一个可匹配的"*/"时才结束匹配, 而对于本例,不是我们最终想要的结果。]] print(string.gsub(test, "/%*.-%*/", "<COMMENT>")) --> int x; <COMMENT> int y; <COMMENT> --[[ '-'使用最短匹配,当找到第一个可匹配的"*/"时就结束匹配, 对于本例,这才是我们想要的结果。]]
Q:什么是捕获?
A:”pattern”可以在内部用()括起一个”sub-pattern”,这些”sub-pattern”被称为捕获物。当匹配成功时,由捕获物匹配到的字符串中的子串被保存起来用于未来的用途。捕获物以它们左括号的次序来编号。例如,对于
(a*(.)%w(%s*)),字符串中匹配到
a*(.)%w(%s*)的部分保存在第一个捕获物中(因此是编号1);由
.匹配到的字符是2号捕获物,匹配到
%s*的那部分是3号。
[code]pair = "name = Anna" --[[ "string.find()"在指定字符串中查找匹配"pattern"的子串, 返回子串的起始和终止位置。如果"pattern"中指定了捕获,则额外返回捕获物。]] _, _, key, value = string.find(pair, "(%a+)%s*=%s*(%a+)") print(key, value) --> name Anna -- 捕获物1号和2号。 date = "17/7/1990" _, _, d, m, y = string.find(date, "(%d+)/(%d+)/(%d+)") print(d, m, y) --> 17 7 1990 -- 捕获物1号、2号和3号。
使用
%d(d是1到9之间的任一数字)的形式使用捕获物。 比如需要匹配一个单引号或双引号引起来的句子,最开始的”pattern”可能这么写:
'["'].-["']',但是这样对于”it’s all right”这个句子会遇到麻烦,因为双引号中包含单引号,所以此时就需要用到捕获,
[code]s = [[then he said: "it's all right"!]] --[[ "%1"代表使用第一个捕获物。 第一个捕获如果匹配的是双引号,那么第一个捕获物就是双引号; 第一个捕获如果匹配的是单引号,那么第一个捕获物就是单引号。]] a, b, c, quotedPart = string.find(s, "([\"'])(.-)%1") print(quotedPart) --> it's all right print(c) --> " -- 这里可以看出来捕获的是双引号。
附加:
1、Lua中的字符串中的任一字符值都是不能被改变的,字符串库中的函数都不会改变参数中字符串的值,而是返回一个新的字符串。如果想改变字符串变量的值,请对其重新赋值,[code]s = string.sub(s, i, j)
2、”Character Class”定义了很多常用的”pattern”,
[code][a-z] <--> %l [0-9] <--> %d [^%s] <--> %S ...
所以请尽量使用”Character Class”提供的常用”pattern”,即简便,又不会出错。
相关文章推荐
- protoc-gen-lua Extensions 中只有repeated 导致 Crash
- C#Light 和 uLua的对比第二弹
- 最近关于evaluation model的进阶理解(待更新)
- Lua Challenge -- From Python Challenge
- Mac平台中编译安装Lua运行环境及Hello Lua实例
- [算法]Evaluate Reverse Polish Notation
- ulua slua 下载地址
- Lua实现在字符之间插入指定字符
- lua中实现倒计时
- Lua编码的那些陷阱
- lua中的require机制
- lua 重新加载module
- lua 中 . 和 : 的区别
- Lua语言基础
- lua53
- 【SPOJ-ARTHEVAL】Arithmetic Evaluation【表达式求值】
- lua程序:猜数字
- lua中Sprite读取图片,缓存问题,会读取到上次保存的图片
- ubuntu lua安装
- luajit stack traceback() 显示不全