首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
Lua - 基础知识
Lua - 环境与模块
Lua - 函数与面向对象
Lua - 标准库
Lua - 协程 Coroutine
Lua - Table 数据结构
Lua - 常用的 C API
Lua - Lua 与 C/C++ 交互
Lua - 编译 Lua 字节码
Lua - LuaJIT 介绍
附录一 Lua 5.1 程序接口
附录二 Lua 5.2 程序接口
当前位置:
首页>>
技术小册>>
Lua编程入门
小册名称:Lua编程入门
## String string.byte string.char string.dump string.find string.format string.gmatch string.gsub string.len string.lower string.match string.rep string.reverse string.sub string.upper > 在string库中功能最强大的函数是:string.find(字符串查找),string.gsub(全局字符串替换),and string.gfind(全局字符串查找)。这些函数都是基于模式匹配的。 > 与其他脚本语言不同的是,Lua并不使用POSIX规范的正则表达式(也写作regexp)来进行模式匹配。主要的原因出于程序大小方面的考虑:实现一个典型的符合POSIX标准的regexp大概需要4000行代码,这比整个Lua标准库加在一起都大。权衡之下,Lua中的模式匹配的实现只用了500行代码,当然这意味着不可能实现POSIX所规范的所有更能。然而,Lua中的模式匹配功能是很强大的,并且包含了一些使用标准POSIX模式匹配不容易实现的功能。 ### (1) pattern 模式 下面的表列出了Lua支持的所有字符类: . 任意字符 %a 字母 %c 控制字符 %d 数字 %l 小写字母 %p 标点字符 %s 空白符 %u 大写字母 %w 字母和数字 %x 十六进制数字 %z 代表0的字符 可以使用修饰符来修饰模式增强模式的表达能力,Lua中的模式修饰符有四个: + 匹配前一字符1次或多次 * 匹配前一字符0次或多次 - 匹配前一字符0次或多次 ? 匹配前一字符0次或1次 '%b' 用来匹配对称的字符。常写为 '%bxy' ,x和y是任意两个不同的字符;x作为匹配的开始,y作为匹配的结束。比如,'%b()' 匹配以 '(' 开始,以 ')' 结束的字符串: print(string.gsub("a (enclosed (in) parentheses) line", "%b()", "")) --> a line 常用的这种模式有:'%b()' ,'%b[]','%b%{%}' 和 '%b<>'。你也可以使用任何字符作为分隔符。 ### (2) capture 捕获 Capture是这样一种机制:可以使用模式串的一部分匹配目标串的一部分。将你想捕获的模式用圆括号括起来,就指定了一个capture。 pair = "name = Anna" _, _, key, value = string.find(pair, "(%a+)%s*=%s*(%a+)") print(key, value) --> name Anna ### (3) string.find 字符串查找 string.find 的基本应用就是用来在目标串(subject string)内搜索匹配指定的模式的串,函数返回两个值:匹配串开始索引和结束索引。 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(s, "l") print(i, j) --> 3 3 print(string.find(s, "lll")) --> nil string.find函数第三个参数是可选的:标示目标串中搜索的起始位置。 在string.find使用captures的时候,函数会返回捕获的值作为额外的结果: pair = "name = Anna" _, _, key, value = string.find(pair, "(%a+)%s*=%s*(%a+)") print(key, value) --> name Anna 看个例子,假定你想查找一个字符串中单引号或者双引号引起来的子串,你可能使用模式 '["'].-["']',但是这个模式对处理类似字符串 "it's all right" 会出问题。为了解决这个问题,可以使用向前引用,使用捕获的第一个引号来表示第二个引号: s = [[then he said: "it's all right"!]] a, b, c, quotedPart = string.find(s, "(["'])(.-)%1") print(quotedPart) --> it's all right print(c) --> " ### (4) string.gmatch 全局字符串查找 string.gfind 函数比较适合用于范性 for 循环。他可以遍历一个字符串内所有匹配模式的子串。 words = {} for w in string.gmatch("nick takes a stroll", "%a+") do table.insert(words, w) end **URL解码** function unescape(s) s = string.gsub(s, "+", " ") s = string.gsub(s, "%%(%x%x)", function(h) return string.char(tonumber(h, 16)) end) return s end print(unescape("a%2Bb+%3D+c")) -- a+b = c 对于name=value对,我们使用gfind解码,因为names和values都不能包含 '&' 和 '='我们可以用模式 '[^&=]+' 匹配他们: cgi = {} function decode (s) for name, value in string.gmatch(s, "([^&=]+)=([^&=]+)") do name = unescape(name) value = unescape(value) cgi[name] = value end end **URL编码** 这个函数将所有的特殊字符转换成 '%' 后跟字符对应的ASCII码转换成两位的16进制数字(不足两位,前面补0),然后将空白转换为 '+': function escape(s) s = string.gsub(s, "([&=+%c])", function(c) return string.format("%%%02X", string.byte(c)) end) s = string.gsub(s, " ", "+") return s end function encode(t) local s = "" for k, v in pairs(t) do s = s .. "&" .. escape(k) .. "=" .. escape(v) end return string.sub(s, 2) -- remove first '&' end t = {name = "al", query = "a+b = c", q = "yes or no"} print(encode(t)) --> q=yes+or+no&query=a%2Bb+%3D+c&name=al ### (5) string.gsub 全局字符串替换 string.gsub 函数有三个参数:目标串,模式串,替换串,第四个参数是可选的,用来限制替换的数量。 print(string.gsub("nck eats fish", "fish", "chips")) --> nick eats chips 1 string.gsub 的第二个返回值表示他进行替换操作的次数: print(string.gsub("fish eats fish", "fish", "chips")) --> chips eats chips 2 使用模式: print(string.gsub("nick eats fish", "[AEIOUaeiou]", ".")) --> n.ck ..ts f.sh 4 使用捕获: print(string.gsub("nick eats fish", "([AEIOUaeiou])", "(%1)")) --> n(i)ck (e)(a)ts f(i)sh 4 使用替换函数: function f(s) print("found " .. s) end string.gsub("Nick is taking a walk today", "%a+", f) 输出: found Nick found is found taking found a found walk found today ### (6) string.sub, string.byte, string.format s = "[in brackets]" print(string.sub(s, 2, -2)) --> in brackets string.char 函数和 string.byte 函数用来将字符在字符和数字之间转换,string.char 获取0个或多个整数,将每一个数字转换成字符,然后返回一个所有这些字符连接起来的字符串。string.byte(s, i) 将字符串s的第i个字符的转换成整数。 print(string.char(97)) --> a i = 99; print(string.char(i, i+1, i+2)) --> cde print(string.byte("abc")) --> 97 print(string.byte("abc", 2)) --> 98 print(string.byte("abc", -1)) --> 99 string.format 和 C 语言的 printf 函数几乎一模一样,你完全可以照 C 语言的 printf 来使用这个函数,第一个参数为格式化串:由指示符和控制格式的字符组成。指示符后的控制格式的字符可以为:十进制'd';十六进制'x';八进制'o';浮点数'f';字符串's'。 print(string.format("pi = %.4f", 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> ## Table table.concat table.insert table.maxn table.remove table.sort ### (1) table.getn print(table.getn{10,2,4}) --> 3 print(table.getn{10,2,nil}) --> 2 print(table.getn{10,2,nil; n=3}) --> 3 print(table.getn{n=1000}) --> 1000 a = {} print(table.getn(a)) --> 0 table.setn(a, 10000) print(table.getn(a)) --> 10000 a = {n=10} print(table.getn(a)) --> 10 table.setn(a, 10000) print(table.getn(a)) --> 10000 ### (2) table.insert, table.remove table.isnert(table, value, position) table.remove(table, position) table库提供了从一个list的任意位置插入和删除元素的函数。table.insert函数在array指定位置插入一个元素,并将后面所有其他的元素后移。 a = {} for line in io.lines() do table.insert(a, line) end print(table.getn(a)) --> (number of lines read) table.remove 函数删除数组中指定位置的元素,并返回这个元素,所有后面的元素前移,并且数组的大小改变。不带位置参数调用的时候,他删除array的最后一个元素。 ### (3) table.sort table.sort 有两个参数,存放元素的array和排序函数,排序函数有两个参数并且如果在array中排序后第一个参数在第二个参数前面,排序函数必须返回true。如果未提供排序函数,sort使用默认的小于操作符进行比较。 lines = { luaH_set = 10, luaH_get = 24, luaH_present = 48, } function pairsByKeys (t, f) local a = {} for n in pairs(t) do table.insert(a, n) end table.sort(a, f) local i = 0 -- iterator variable local iter = function () -- iterator function i = i + 1 if a[i] == nil then return nil else return a[i], t[a[i]] end end return iter end for name, line in pairsByKeys(lines) do print(name, line) end 打印结果: luaH_get 24 luaH_present 48 luaH_set 10 ## Coroutine coroutine.create coroutine.resume coroutine.running coroutine.status coroutine.wrap coroutine.yield ## Math math.abs math.acos math.asin math.atan math.atan2 math.ceil math.cos math.cosh math.deg math.exp math.floor math.fmod math.frexp math.huge math.ldexp math.log math.log10 math.max math.min math.modf math.pi math.pow math.rad math.random math.randomseed math.sin math.sinh math.sqrt math.tan math.tanh ## IO io.close io.flush io.input io.lines io.open io.output io.popen io.read io.stderr io.stdin io.stdout io.tmpfile io.type io.write ## OS os.clock os.date os.difftime os.execute os.exit os.getenv os.remove os.rename os.setlocale os.time os.tmpname ## File file:close file:flush file:lines file:read file:seek file:setvbuf file:write ## Debug debug.debug debug.getfenv debug.gethook debug.getinfo debug.getlocal debug.getmetatable debug.getregistry debug.getupvalue debug.setfenv debug.sethook debug.setlocal debug.setmetatable debug.setupvalue debug.traceback
上一篇:
Lua - 函数与面向对象
下一篇:
Lua - 协程 Coroutine
该分类下的相关小册推荐:
Lua入门教程