标准库

String

  1. string.byte
  2. string.char
  3. string.dump
  4. string.find
  5. string.format
  6. string.gmatch
  7. string.gsub
  8. string.len
  9. string.lower
  10. string.match
  11. string.rep
  12. string.reverse
  13. string.sub
  14. 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支持的所有字符类:

  1. . 任意字符
  2. %a 字母
  3. %c 控制字符
  4. %d 数字
  5. %l 小写字母
  6. %p 标点字符
  7. %s 空白符
  8. %u 大写字母
  9. %w 字母和数字
  10. %x 十六进制数字
  11. %z 代表0的字符

可以使用修饰符来修饰模式增强模式的表达能力,Lua中的模式修饰符有四个:

  1. + 匹配前一字符1次或多次
  2. * 匹配前一字符0次或多次
  3. - 匹配前一字符0次或多次
  4. ? 匹配前一字符0次或1

‘%b’ 用来匹配对称的字符。常写为 ‘%bxy’ ,x和y是任意两个不同的字符;x作为匹配的开始,y作为匹配的结束。比如,’%b()’ 匹配以 ‘(‘ 开始,以 ‘)’ 结束的字符串:

  1. print(string.gsub("a (enclosed (in) parentheses) line", "%b()", "")) --> a line

常用的这种模式有:’%b()’ ,’%b[]’,’%b%{%}’ 和 ‘%b<>’。你也可以使用任何字符作为分隔符。

(2) capture 捕获

Capture是这样一种机制:可以使用模式串的一部分匹配目标串的一部分。将你想捕获的模式用圆括号括起来,就指定了一个capture。

  1. pair = "name = Anna"
  2. _, _, key, value = string.find(pair, "(%a+)%s*=%s*(%a+)")
  3. print(key, value) --> name Anna

(3) string.find 字符串查找

string.find 的基本应用就是用来在目标串(subject string)内搜索匹配指定的模式的串,函数返回两个值:匹配串开始索引和结束索引。

  1. s = "hello world"
  2. i, j = string.find(s, "hello")
  3. print(i, j) --> 1 5
  4. print(string.sub(s, i, j)) --> hello
  5. print(string.find(s, "world")) --> 7 11
  6. i, j = string.find(s, "l")
  7. print(i, j) --> 3 3
  8. print(string.find(s, "lll")) --> nil

string.find函数第三个参数是可选的:标示目标串中搜索的起始位置。

在string.find使用captures的时候,函数会返回捕获的值作为额外的结果:

  1. pair = "name = Anna"
  2. _, _, key, value = string.find(pair, "(%a+)%s*=%s*(%a+)")
  3. print(key, value) --> name Anna

看个例子,假定你想查找一个字符串中单引号或者双引号引起来的子串,你可能使用模式 ‘[“‘].-[“‘]’,但是这个模式对处理类似字符串 “it’s all right” 会出问题。为了解决这个问题,可以使用向前引用,使用捕获的第一个引号来表示第二个引号:

  1. s = [[then he said: "it's all right"!]]
  2. a, b, c, quotedPart = string.find(s, "(["'])(.-)%1")
  3. print(quotedPart) --> it's all right
  4. print(c) --> "

(4) string.gmatch 全局字符串查找

string.gfind 函数比较适合用于范性 for 循环。他可以遍历一个字符串内所有匹配模式的子串。

  1. words = {}
  2. for w in string.gmatch("nick takes a stroll", "%a+") do
  3. table.insert(words, w)
  4. end

URL解码

  1. function unescape(s)
  2. s = string.gsub(s, "+", " ")
  3. s = string.gsub(s, "%%(%x%x)", function(h)
  4. return string.char(tonumber(h, 16))
  5. end)
  6. return s
  7. end
  8. print(unescape("a%2Bb+%3D+c")) -- a+b = c

对于name=value对,我们使用gfind解码,因为names和values都不能包含 ‘&’ 和 ‘=’我们可以用模式 ‘[^&=]+’ 匹配他们:

  1. cgi = {}
  2. function decode (s)
  3. for name, value in string.gmatch(s, "([^&=]+)=([^&=]+)") do
  4. name = unescape(name)
  5. value = unescape(value)
  6. cgi[name] = value
  7. end
  8. end

URL编码

这个函数将所有的特殊字符转换成 ‘%’ 后跟字符对应的ASCII码转换成两位的16进制数字(不足两位,前面补0),然后将空白转换为 ‘+’:

  1. function escape(s)
  2. s = string.gsub(s, "([&=+%c])", function(c)
  3. return string.format("%%%02X", string.byte(c))
  4. end)
  5. s = string.gsub(s, " ", "+")
  6. return s
  7. end
  8. function encode(t)
  9. local s = ""
  10. for k, v in pairs(t) do
  11. s = s .. "&" .. escape(k) .. "=" .. escape(v)
  12. end
  13. return string.sub(s, 2) -- remove first '&'
  14. end
  15. t = {name = "al", query = "a+b = c", q = "yes or no"}
  16. print(encode(t)) --> q=yes+or+no&query=a%2Bb+%3D+c&name=al

(5) string.gsub 全局字符串替换

string.gsub 函数有三个参数:目标串,模式串,替换串,第四个参数是可选的,用来限制替换的数量。

  1. print(string.gsub("nck eats fish", "fish", "chips")) --> nick eats chips 1

string.gsub 的第二个返回值表示他进行替换操作的次数:

  1. print(string.gsub("fish eats fish", "fish", "chips")) --> chips eats chips 2

使用模式:

  1. print(string.gsub("nick eats fish", "[AEIOUaeiou]", ".")) --> n.ck ..ts f.sh 4

使用捕获:

  1. print(string.gsub("nick eats fish", "([AEIOUaeiou])", "(%1)")) --> n(i)ck (e)(a)ts f(i)sh 4

使用替换函数:

  1. function f(s)
  2. print("found " .. s)
  3. end
  4. string.gsub("Nick is taking a walk today", "%a+", f)
  5. 输出:
  6. found Nick
  7. found is
  8. found taking
  9. found a
  10. found walk
  11. found today

(6) string.sub, string.byte, string.format

  1. s = "[in brackets]"
  2. print(string.sub(s, 2, -2)) --> in brackets

string.char 函数和 string.byte 函数用来将字符在字符和数字之间转换,string.char 获取0个或多个整数,将每一个数字转换成字符,然后返回一个所有这些字符连接起来的字符串。string.byte(s, i) 将字符串s的第i个字符的转换成整数。

  1. print(string.char(97)) --> a
  2. i = 99; print(string.char(i, i+1, i+2)) --> cde
  3. print(string.byte("abc")) --> 97
  4. print(string.byte("abc", 2)) --> 98
  5. print(string.byte("abc", -1)) --> 99

string.format 和 C 语言的 printf 函数几乎一模一样,你完全可以照 C 语言的 printf 来使用这个函数,第一个参数为格式化串:由指示符和控制格式的字符组成。指示符后的控制格式的字符可以为:十进制’d’;十六进制’x’;八进制’o’;浮点数’f’;字符串’s’。

  1. print(string.format("pi = %.4f", PI)) --> pi = 3.1416
  2. d = 5; m = 11; y = 1990
  3. print(string.format("%02d/%02d/%04d", d, m, y)) --> 05/11/1990
  4. tag, title = "h1", "a title"
  5. print(string.format("<%s>%s</%s>", tag, title, tag)) --> <h1>a title</h1>

Table

  1. table.concat
  2. table.insert
  3. table.maxn
  4. table.remove
  5. table.sort

(1) table.getn

  1. print(table.getn{10,2,4}) --> 3
  2. print(table.getn{10,2,nil}) --> 2
  3. print(table.getn{10,2,nil; n=3}) --> 3
  4. print(table.getn{n=1000}) --> 1000
  5. a = {}
  6. print(table.getn(a)) --> 0
  7. table.setn(a, 10000)
  8. print(table.getn(a)) --> 10000
  9. a = {n=10}
  10. print(table.getn(a)) --> 10
  11. table.setn(a, 10000)
  12. print(table.getn(a)) --> 10000

(2) table.insert, table.remove

  1. table.isnert(table, value, position)
  2. table.remove(table, position)

table库提供了从一个list的任意位置插入和删除元素的函数。table.insert函数在array指定位置插入一个元素,并将后面所有其他的元素后移。

  1. a = {}
  2. for line in io.lines() do
  3. table.insert(a, line)
  4. end
  5. print(table.getn(a)) --> (number of lines read)

table.remove 函数删除数组中指定位置的元素,并返回这个元素,所有后面的元素前移,并且数组的大小改变。不带位置参数调用的时候,他删除array的最后一个元素。

(3) table.sort

table.sort 有两个参数,存放元素的array和排序函数,排序函数有两个参数并且如果在array中排序后第一个参数在第二个参数前面,排序函数必须返回true。如果未提供排序函数,sort使用默认的小于操作符进行比较。

  1. lines = {
  2. luaH_set = 10,
  3. luaH_get = 24,
  4. luaH_present = 48,
  5. }
  6. function pairsByKeys (t, f)
  7. local a = {}
  8. for n in pairs(t) do table.insert(a, n) end
  9. table.sort(a, f)
  10. local i = 0 -- iterator variable
  11. local iter = function () -- iterator function
  12. i = i + 1
  13. if a[i] == nil then return nil
  14. else return a[i], t[a[i]]
  15. end
  16. end
  17. return iter
  18. end
  19. for name, line in pairsByKeys(lines) do
  20. print(name, line)
  21. end

打印结果:

  1. luaH_get 24
  2. luaH_present 48
  3. luaH_set 10

Coroutine

  1. coroutine.create
  2. coroutine.resume
  3. coroutine.running
  4. coroutine.status
  5. coroutine.wrap
  6. coroutine.yield

Math

  1. math.abs
  2. math.acos
  3. math.asin
  4. math.atan
  5. math.atan2
  6. math.ceil
  7. math.cos
  8. math.cosh
  9. math.deg
  10. math.exp
  11. math.floor
  12. math.fmod
  13. math.frexp
  14. math.huge
  15. math.ldexp
  16. math.log
  17. math.log10
  18. math.max
  19. math.min
  20. math.modf
  21. math.pi
  22. math.pow
  23. math.rad
  24. math.random
  25. math.randomseed
  26. math.sin
  27. math.sinh
  28. math.sqrt
  29. math.tan
  30. math.tanh

IO

  1. io.close
  2. io.flush
  3. io.input
  4. io.lines
  5. io.open
  6. io.output
  7. io.popen
  8. io.read
  9. io.stderr
  10. io.stdin
  11. io.stdout
  12. io.tmpfile
  13. io.type
  14. io.write

OS

  1. os.clock
  2. os.date
  3. os.difftime
  4. os.execute
  5. os.exit
  6. os.getenv
  7. os.remove
  8. os.rename
  9. os.setlocale
  10. os.time
  11. os.tmpname

File

  1. file:close
  2. file:flush
  3. file:lines
  4. file:read
  5. file:seek
  6. file:setvbuf
  7. file:write

Debug

  1. debug.debug
  2. debug.getfenv
  3. debug.gethook
  4. debug.getinfo
  5. debug.getlocal
  6. debug.getmetatable
  7. debug.getregistry
  8. debug.getupvalue
  9. debug.setfenv
  10. debug.sethook
  11. debug.setlocal
  12. debug.setmetatable
  13. debug.setupvalue
  14. debug.traceback

导航