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庫中功能最強(qiáng)大的函數(shù)是:string.find(字符串查找),string.gsub(全局字符串替換),and string.gfind(全局字符串查找)。這些函數(shù)都是基于模式匹配的。
與其他腳本語言不同的是,Lua并不使用POSIX規(guī)范的正則表達(dá)式(也寫作regexp)來進(jìn)行模式匹配。主要的原因出于程序大小方面的考慮:實(shí)現(xiàn)一個典型的符合POSIX標(biāo)準(zhǔn)的regexp大概需要4000行代碼,這比整個Lua標(biāo)準(zhǔn)庫加在一起都大。權(quán)衡之下,Lua中的模式匹配的實(shí)現(xiàn)只用了500行代碼,當(dāng)然這意味著不可能實(shí)現(xiàn)POSIX所規(guī)范的所有更能。然而,Lua中的模式匹配功能是很強(qiáng)大的,并且包含了一些使用標(biāo)準(zhǔn)POSIX模式匹配不容易實(shí)現(xiàn)的功能。
下面的表列出了Lua支持的所有字符類:
. 任意字符
%a 字母
%c 控制字符
%d 數(shù)字
%l 小寫字母
%p 標(biāo)點(diǎn)字符
%s 空白符
%u 大寫字母
%w 字母和數(shù)字
%x 十六進(jìn)制數(shù)字
%z 代表0的字符
可以使用修飾符來修飾模式增強(qiáng)模式的表達(dá)能力,Lua中的模式修飾符有四個:
+ 匹配前一字符1次或多次
* 匹配前一字符0次或多次
- 匹配前一字符0次或多次
? 匹配前一字符0次或1次
'%b' 用來匹配對稱的字符。常寫為 '%bxy' ,x和y是任意兩個不同的字符;x作為匹配的開始,y作為匹配的結(jié)束。比如,'%b()' 匹配以 '(' 開始,以 ')' 結(jié)束的字符串:
print(string.gsub("a (enclosed (in) parentheses) line", "%b()", "")) --> a line
常用的這種模式有:'%b()' ,'%b[]','%b%{%}' 和 '%b<>'。你也可以使用任何字符作為分隔符。
Capture是這樣一種機(jī)制:可以使用模式串的一部分匹配目標(biāo)串的一部分。將你想捕獲的模式用圓括號括起來,就指定了一個capture。
pair = "name = Anna"
_, _, key, value = string.find(pair, "(%a+)%s*=%s*(%a+)")
print(key, value) --> name Anna
string.find 的基本應(yīng)用就是用來在目標(biāo)串(subject string)內(nèi)搜索匹配指定的模式的串,函數(shù)返回兩個值:匹配串開始索引和結(jié)束索引。
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函數(shù)第三個參數(shù)是可選的:標(biāo)示目標(biāo)串中搜索的起始位置。
在string.find使用captures的時候,函數(shù)會返回捕獲的值作為額外的結(jié)果:
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) --> "
string.gfind 函數(shù)比較適合用于范性 for 循環(huán)。他可以遍歷一個字符串內(nèi)所有匹配模式的子串。
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解碼,因?yàn)閚ames和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編碼
這個函數(shù)將所有的特殊字符轉(zhuǎn)換成 '%' 后跟字符對應(yīng)的ASCII碼轉(zhuǎn)換成兩位的16進(jìn)制數(shù)字(不足兩位,前面補(bǔ)0),然后將空白轉(zhuǎn)換為 '+':
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
string.gsub 函數(shù)有三個參數(shù):目標(biāo)串,模式串,替換串,第四個參數(shù)是可選的,用來限制替換的數(shù)量。
print(string.gsub("nck eats fish", "fish", "chips")) --> nick eats chips 1
string.gsub 的第二個返回值表示他進(jìn)行替換操作的次數(shù):
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
使用替換函數(shù):
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
s = "[in brackets]"
print(string.sub(s, 2, -2)) --> in brackets
string.char 函數(shù)和 string.byte 函數(shù)用來將字符在字符和數(shù)字之間轉(zhuǎn)換,string.char 獲取0個或多個整數(shù),將每一個數(shù)字轉(zhuǎn)換成字符,然后返回一個所有這些字符連接起來的字符串。string.byte(s, i) 將字符串s的第i個字符的轉(zhuǎn)換成整數(shù)。
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 函數(shù)幾乎一模一樣,你完全可以照 C 語言的 printf 來使用這個函數(shù),第一個參數(shù)為格式化串:由指示符和控制格式的字符組成。指示符后的控制格式的字符可以為:十進(jìn)制'd';十六進(jìn)制'x';八進(jìn)制'o';浮點(diǎn)數(shù)'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.concat
table.insert
table.maxn
table.remove
table.sort
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
table.isnert(table, value, position)
table.remove(table, position)
table庫提供了從一個list的任意位置插入和刪除元素的函數(shù)。table.insert函數(shù)在array指定位置插入一個元素,并將后面所有其他的元素后移。
a = {}
for line in io.lines() do
table.insert(a, line)
end
print(table.getn(a)) --> (number of lines read)
table.remove 函數(shù)刪除數(shù)組中指定位置的元素,并返回這個元素,所有后面的元素前移,并且數(shù)組的大小改變。不帶位置參數(shù)調(diào)用的時候,他刪除array的最后一個元素。
table.sort 有兩個參數(shù),存放元素的array和排序函數(shù),排序函數(shù)有兩個參數(shù)并且如果在array中排序后第一個參數(shù)在第二個參數(shù)前面,排序函數(shù)必須返回true。如果未提供排序函數(shù),sort使用默認(rèn)的小于操作符進(jìn)行比較。
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
打印結(jié)果:
luaH_get 24
luaH_present 48
luaH_set 10
coroutine.create
coroutine.resume
coroutine.running
coroutine.status
coroutine.wrap
coroutine.yield
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.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.clock
os.date
os.difftime
os.execute
os.exit
os.getenv
os.remove
os.rename
os.setlocale
os.time
os.tmpname
file:close
file:flush
file:lines
file:read
file:seek
file:setvbuf
file:write
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
更多建議: