Lua中的捕獲機(jī)制和轉(zhuǎn)換技巧介紹
捕獲
捕獲是這樣一種機(jī)制:可以使用模式串的一部分匹配目標(biāo)串的一部分。將你想捕獲的模式用圓括號(hào)括起來(lái),就指定了一個(gè)捕獲。
在string.find使用捕獲的時(shí)候,函數(shù)會(huì)返回捕獲的值作為額外的結(jié)果。這常被用來(lái)將一個(gè)目標(biāo)串拆分成多個(gè):
pair = "name = Anna"
_, _, key, value = string.find(pair, "(%a+)%s*=%s*(%a+)")
print(key, value) --> name Anna
'%a+' 表示菲空的字母序列;'%s*' 表示0個(gè)或多個(gè)空白。在上面的例子中,整個(gè)模式代表:一個(gè)字母序列,后面是任意多個(gè)空白,然后是 '=' 再后面是任意多個(gè)空白,然后是一個(gè)字母序列。兩個(gè)字母序列都是使用圓括號(hào)括起來(lái)的子模式,當(dāng)他們被匹配的時(shí)候,他們就會(huì)被捕獲。當(dāng)匹配發(fā)生的時(shí)候,find函數(shù)總是先返回匹配串的索引下標(biāo)(上面例子中我們存儲(chǔ)啞元變量 _ 中),然后返回子模式匹配的捕獲部分。下面的例子情況類似:
date = "17/7/1990"
_, _, d, m, y = string.find(date, "(%d+)/(%d+)/(%d+)")
print(d, m, y) --> 17 7 1990
我們可以在模式中使用向前引用,'%d'(d代表1-9的數(shù)字)表示第d個(gè)捕獲的拷貝。
看個(gè)例子,假定你想查找一個(gè)字符串中單引號(hào)或者雙引號(hào)引起來(lái)的子串,你可能使用模式 '["'].-["']',但是這個(gè)模式對(duì)處理類似字符串 "it's all right" 會(huì)出問(wèn)題。為了解決這個(gè)問(wèn)題,可以使用向前引用,使用捕獲的第一個(gè)引號(hào)來(lái)表示第二個(gè)引號(hào):
s = [[then he said: "it's all right"!]]
a, b, c, quotedPart = string.find(s, "(["'])(.-)%1")
print(quotedPart) --> it's all right
print(c) --> "
第一個(gè)捕獲是引號(hào)字符本身,第二個(gè)捕獲是引號(hào)中間的內(nèi)容('.-' 匹配引號(hào)中間的子串)。
捕獲值的第三個(gè)應(yīng)用是用在函數(shù)gsub中。與其他模式一樣,gsub的替換串可以包含 '%d',當(dāng)替換發(fā)生時(shí)他被轉(zhuǎn)換為對(duì)應(yīng)的捕獲值。(順便說(shuō)一下,由于存在這些情況,替換串中的字符 '%' 必須用 "%%" 表示)。下面例子中,對(duì)一個(gè)字符串中的每一個(gè)字母進(jìn)行復(fù)制,并用連字符將復(fù)制的字母和原字母連接起來(lái):
print(string.gsub("hello Lua!", "(%a)", "%1-%1"))
--> h-he-el-ll-lo-o L-Lu-ua-a!
下面代碼互換相鄰的字符:
print(string.gsub("hello Lua", "(.)(.)", "%2%1"))
--> ehll ouLa
讓我們看一個(gè)更有用的例子,寫(xiě)一個(gè)格式轉(zhuǎn)換器:從命令行獲取LaTeX風(fēng)格的字符串,形如:
\command{some text}
將它們轉(zhuǎn)換為XML風(fēng)格的字符串:
<command>some text</command>
對(duì)于這種情況,下面的代碼可以實(shí)現(xiàn)這個(gè)功能:
s = string.gsub(s, "\\(%a+){(.-)}", "<%1>%2</%1>")
比如,如果字符串s為:
the \quote{task} is to \em{change} that.
調(diào)用gsub之后,轉(zhuǎn)換為:
the <quote>task</quote> is to change that.
另一個(gè)有用的例子是去除字符串首尾的空格:
function trim (s)
return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
end
注意模式串的用法,兩個(gè)定位符('^' 和 '$')保證我們獲取的是整個(gè)字符串。因?yàn)?,兩個(gè) '%s*' 匹配首尾的所有空格,'.-' 匹配剩余部分。還有一點(diǎn)需要注意的是gsub返回兩個(gè)值,我們使用額外的圓括號(hào)丟棄多余的結(jié)果(替換發(fā)生的次數(shù))。
最后一個(gè)捕獲值應(yīng)用之處可能是功能最強(qiáng)大的。我們可以使用一個(gè)函數(shù)作為string.gsub的第三個(gè)參數(shù)調(diào)用gsub。在這種情況下,string.gsub每次發(fā)現(xiàn)一個(gè)匹配的時(shí)候就會(huì)調(diào)用給定的作為參數(shù)的函數(shù),捕獲值可以作為被調(diào)用的這個(gè)函數(shù)的參數(shù),而這個(gè)函數(shù)的返回值作為gsub的替換串。先看一個(gè)簡(jiǎn)單的例子,下面的代碼將一個(gè)字符串中全局變量$varname出現(xiàn)的地方替換為變量varname的值:
function expand (s)
s = string.gsub(s, "$(%w+)", function (n)
return _G[n]
end)
return s
end
name = "Lua"; status = "great"
print(expand("$name is $status, isn't it?"))
--> Lua is great, isn't it?
如果你不能確定給定的變量是否為string類型,可以使用tostring進(jìn)行轉(zhuǎn)換:
function expand (s)
return (string.gsub(s, "$(%w+)", function (n)
return tostring(_G[n])
end))
end
print(expand("print = $print; a = $a"))
--> print = function: 0x8050ce0; a = nil
下面是一個(gè)稍微復(fù)雜點(diǎn)的例子,使用loadstring來(lái)計(jì)算一段文本內(nèi)$后面跟著一對(duì)方括號(hào)內(nèi)表達(dá)式的值:
s = "sin(3) = $[math.sin(3)]; 2^5 = $[2^5]"
print((string.gsub(s, "$(%b[])", function (x)
x = "return " .. string.sub(x, 2, -2)
local f = loadstring(x)
return f()
end)))
--> sin(3) = 0.1411200080598672; 2^5 = 32
第一次匹配是 "$[math.sin(3)]",對(duì)應(yīng)的捕獲為 "[math.sin(3)]",調(diào)用string.sub去掉首尾的方括號(hào),
所以被加載執(zhí)行的字符串是 "return math.sin(3)","$[2^5]" 的匹配情況類似。
我們常常需要使用string.gsub遍歷字符串,而對(duì)返回結(jié)果不感興趣。比如,我們收集一個(gè)字符串中所有的單詞,然后插入到一個(gè)表中:
words = {}
string.gsub(s, "(%a+)", function (w)
table.insert(words, w)
end)
如果字符串s為 "hello hi, again!",上面代碼的結(jié)果將是:
{"hello", "hi", "again"}
使用string.gfind函數(shù)可以簡(jiǎn)化上面的代碼:
words = {}
for w in string.gfind(s, "(%a)") do
table.insert(words, w)
end
gfind函數(shù)比較適合用于范性for循環(huán)。他可以遍歷一個(gè)字符串內(nèi)所有匹配模式的子串。我們可以進(jìn)一步的簡(jiǎn)化上面的代碼,調(diào)用gfind函數(shù)的時(shí)候,如果不顯示的指定捕獲,函數(shù)將捕獲整個(gè)匹配模式。所以,上面代碼可以簡(jiǎn)化為:
words = {}
for w in string.gfind(s, "%a") do
table.insert(words, w)
end
下面的例子我們使用URL編碼,URL編碼是HTTP協(xié)議來(lái)用發(fā)送URL中的參數(shù)進(jìn)行的編碼。這種編碼將一些特殊字符(比如 '='、'&'、'+')轉(zhuǎn)換為 "%XX" 形式的編碼,其中XX是字符的16進(jìn)制表示,然后將空白轉(zhuǎn)換成 '+'。比如,將字符串 "a+b = c" 編碼為 "a%2Bb+%3D+c"。最后,將參數(shù)名和參數(shù)值之間加一個(gè) '=';在name=value對(duì)之間加一個(gè) "&"。比如字符串:
name = "al"; query = "a+b = c"; q="yes or no"
被編碼為:
name=al&query=a%2Bb+%3D+c&q=yes+or+no
現(xiàn)在,假如我們想將這URL解碼并把每個(gè)值存儲(chǔ)到表中,下標(biāo)為對(duì)應(yīng)的名字。下面的函數(shù)實(shí)現(xiàn)了解碼功能:
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
第一個(gè)語(yǔ)句將 '+' 轉(zhuǎn)換成空白,第二個(gè)gsub匹配所有的 '%' 后跟兩個(gè)數(shù)字的16進(jìn)制數(shù),然后調(diào)用一個(gè)匿名函數(shù),匿名函數(shù)將16進(jìn)制數(shù)轉(zhuǎn)換成一個(gè)數(shù)字(tonumber在16進(jìn)制情況下使用的)然后再轉(zhuǎn)化為對(duì)應(yīng)的字符。比如:
print(unescape("a%2Bb+%3D+c")) --> a+b = c
對(duì)于name=value對(duì),我們使用gfind解碼,因?yàn)閚ames和values都不能包含 '&' 和 '='我們可以用模式 '[^&=]+' 匹配他們:
cgi = {}
function decode (s)
for name, value in string.gfind(s, "([^&=]+)=([^&=]+)") do
name = unescape(name)
value = unescape(value)
cgi[name] = value
end
end
調(diào)用gfind函數(shù)匹配所有的name=value對(duì),對(duì)于每一個(gè)name=value對(duì),迭代子將其相對(duì)應(yīng)的捕獲的值返回給變量name和value。循環(huán)體內(nèi)調(diào)用unescape函數(shù)解碼name和value部分,并將其存儲(chǔ)到cgi表中。
與解碼對(duì)應(yīng)的編碼也很容易實(shí)現(xiàn)。首先,我們寫(xiě)一個(gè)escape函數(shù),這個(gè)函數(shù)將所有的特殊字符轉(zhuǎn)換成 '%' 后跟字符對(duì)應(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
編碼函數(shù)遍歷要被編碼的表,構(gòu)造最終的結(jié)果串:
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
轉(zhuǎn)換的技巧(Tricks of the Trade)
模式匹配對(duì)于字符串操縱來(lái)說(shuō)是強(qiáng)大的工具,你可能只需要簡(jiǎn)單的調(diào)用string.gsub和find就可以完成復(fù)雜的操作,然而,因?yàn)樗δ軓?qiáng)大你必須謹(jǐn)慎的使用它,否則會(huì)帶來(lái)意想不到的結(jié)果。
對(duì)正常的解析器而言,模式匹配不是一個(gè)替代品。對(duì)于一個(gè)quick-and-dirty程序,你可以在源代碼上進(jìn)行一些有用的操作,但很難完成一個(gè)高質(zhì)量的產(chǎn)品。前面提到的匹配C程序中注釋的模式是個(gè)很好的例子:'/%*.-%*/'。如果你的程序有一個(gè)字符串包含了"/*",最終你將得到錯(cuò)誤的結(jié)果:
test = [[char s[] = "a /* here"; /* a tricky string */]]
print(string.gsub(test, "/%*.-%*/", "<COMMENT>"))
--> char s[] = "a <COMMENT>
雖然這樣內(nèi)容的字符串很罕見(jiàn),如果是你自己使用的話上面的模式可能還湊活。但你不能將一個(gè)帶有這種毛病的程序作為產(chǎn)品出售。
一般情況下,Lua中的模式匹配效率是不錯(cuò)的:一個(gè)奔騰333MHz機(jī)器在一個(gè)有200K字符的文本內(nèi)匹配所有的單詞(30K的單詞)只需要1/10秒。但是你不能掉以輕心,應(yīng)該一直對(duì)不同的情況特殊對(duì)待,盡可能的更明確的模式描述。一個(gè)限制寬松的模式比限制嚴(yán)格的模式可能慢很多。一個(gè)極端的例子是模式 '(.-)%$' 用來(lái)獲取一個(gè)字符串內(nèi)$符號(hào)以前所有的字符,如果目標(biāo)串中存在$符號(hào),沒(méi)有什么問(wèn)題;但是如果目標(biāo)串中不存在$符號(hào)。上面的算法會(huì)首先從目標(biāo)串的第一個(gè)字符開(kāi)始進(jìn)行匹配,遍歷整個(gè)字符串之后沒(méi)有找到$符號(hào),然后從目標(biāo)串的第二個(gè)字符開(kāi)始進(jìn)行匹配,……這將花費(fèi)原來(lái)平方次冪的時(shí)間,導(dǎo)致在一個(gè)奔騰333MHz的機(jī)器中需要3個(gè)多小時(shí)來(lái)處理一個(gè)200K的文本串??梢允褂孟旅孢@個(gè)模式避免上面的問(wèn)題 '^(.-)%$'。定位符^告訴算法如果在第一個(gè)位置沒(méi)有沒(méi)找到匹配的子串就停止查找。使用這個(gè)定位符之后,同樣的環(huán)境也只需要不到1/10秒的時(shí)間。
也需要小心空模式:匹配空串的模式。比如,如果你打算用模式 '%a*' 匹配名字,你會(huì)發(fā)現(xiàn)到處都是名字:
i, j = string.find(";$% **#$hello13", "%a*")
print(i,j) --> 1 0
這個(gè)例子中調(diào)用string.find正確的在目標(biāo)串的開(kāi)始處匹配了空字符。永遠(yuǎn)不要寫(xiě)一個(gè)以 '-' 開(kāi)頭或者結(jié)尾的模式,因?yàn)樗鼘⑵ヅ淇沾?。這個(gè)修飾符得周圍總是需要一些東西來(lái)定位他的擴(kuò)展。相似的,一個(gè)包含 '.*' 的模式是一個(gè)需要注意的,因?yàn)檫@個(gè)結(jié)構(gòu)可能會(huì)比你預(yù)算的擴(kuò)展的要多。
有時(shí)候,使用Lua本身構(gòu)造模式是很有用的。看一個(gè)例子,我們查找一個(gè)文本中行字符大于70個(gè)的行,也就是匹配一個(gè)非換行符之前有70個(gè)字符的行。我們使用字符類'[^\n]'表示非換行符的字符。所以,我們可以使用這樣一個(gè)模式來(lái)滿足我們的需要:重復(fù)匹配單個(gè)字符的模式70次,后面跟著一個(gè)匹配一個(gè)字符0次或多次的模式。我們不手工來(lái)寫(xiě)這個(gè)最終的模式,而使用函數(shù)string.rep:
pattern = string.rep("[^\n]", 70) .. "[^\n]*"
另一個(gè)例子,假如你想進(jìn)行一個(gè)大小寫(xiě)無(wú)關(guān)的查找。方法之一是將任何一個(gè)字符x變?yōu)樽址?'[xX]'。我們也可以使用一個(gè)函數(shù)進(jìn)行自動(dòng)轉(zhuǎn)換:
function nocase (s)
s = string.gsub(s, "%a", function (c)
return string.format("[%s%s]", string.lower(c),
string.upper(c))
end)
return s
end
print(nocase("Hi there!"))
--> [hH][iI] [tT][hH][eE][rR][eE]!
有時(shí)候你可能想要將字符串s1轉(zhuǎn)化為s2,而不關(guān)心其中的特殊字符。如果字符串s1和s2都是字符串序列,你可以給其中的特殊字符加上轉(zhuǎn)義字符來(lái)實(shí)現(xiàn)。但是如果這些字符串是變量呢,你可以使用gsub來(lái)完成這種轉(zhuǎn)義:
s1 = string.gsub(s1, "(%W)", "%%%1")
s2 = string.gsub(s2, "%%", "%%%%")
在查找串中,我們轉(zhuǎn)義了所有的非字母的字符。在替換串中,我們只轉(zhuǎn)義了 '%' 。另一個(gè)對(duì)模式匹配而言有用的技術(shù)是在進(jìn)行真正處理之前,對(duì)目標(biāo)串先進(jìn)行預(yù)處理。一個(gè)預(yù)處理的簡(jiǎn)單例子是,將一段文本內(nèi)的雙引號(hào)內(nèi)的字符串轉(zhuǎn)換為大寫(xiě),但是要注意雙引號(hào)之間可以包含轉(zhuǎn)義的引號(hào)("""):
這是一個(gè)典型的字符串例子:
"This is "great"!".
我們處理這種情況的方法是,預(yù)處理文本把有問(wèn)題的字符序列轉(zhuǎn)換成其他的格式。比如,我們可以將 """ 編碼為 "\1",但是如果原始的文本中包含 "\1",我們又陷入麻煩之中。一個(gè)避免這個(gè)問(wèn)題的簡(jiǎn)單的方法是將所有 "\x" 類型的編碼為 "\ddd",其中ddd是字符x的十進(jìn)制表示:
function code (s)
return (string.gsub(s, "\\(.)", function (x)
return string.format("\\%03d", string.byte(x))
end))
end
注意,原始串中的 "\ddd" 也會(huì)被編碼,解碼是很容易的:
function decode (s)
return (string.gsub(s, "\\(%d%d%d)", function (d)
return "\" .. string.char(d)
end))
end
如果被編碼的串不包含任何轉(zhuǎn)義符,我們可以簡(jiǎn)單的使用 ' ".-" ' 來(lái)查找雙引號(hào)字符串:
s = [[follows a typical string: "This is "great"!".]]
s = code(s)
s = string.gsub(s, '(".-")', string.upper)
s = decode(s)
print(s)
--> follows a typical string: "THIS IS "GREAT"!".
更緊縮的形式:
print(decode(string.gsub(code(s), '(".-")', string.upper)))
我們回到前面的一個(gè)例子,轉(zhuǎn)換\command{string}這種格式的命令為XML風(fēng)格:
<command>string</command>
但是這一次我們?cè)嫉母袷街锌梢园葱备茏鳛檗D(zhuǎn)義符,這樣就可以使用"\"、"\{" 和 "\}",分別表示 '\'、'{' 和 '}'。為了避免命令和轉(zhuǎn)義的字符混合在一起,我們應(yīng)該首先將原始串中的這些特殊序列重新編碼,然而,與上面的一個(gè)例子不同的是,我們不能轉(zhuǎn)義所有的 \x,因?yàn)檫@樣會(huì)將我們的命令(\command)也轉(zhuǎn)換掉。這里,我們僅當(dāng)x不是字符的時(shí)候才對(duì) \x 進(jìn)行編碼:
function code (s)
return (string.gsub(s, '\\(%A)', function (x)
return string.format(" \\%03d ", string.byte(x))
end))
end
解碼部分和上面那個(gè)例子類似,但是在最終的字符串中不包含反斜杠,所以我們可直接調(diào)用string.char:
function decode (s)
return (string.gsub(s, '\\(%d%d%d)', string.char))
end
s = [[a \emph{command} is written as \\ command\{text\}.]]
s = code(s)
s = string.gsub(s, "\\ (%a+){(.-)}", "<%1>%2</%1>")
print(decode(s))
--> a <emph>command</emph> is written as \command{text}.
我們最后一個(gè)例子是處理CSV(逗號(hào)分割)的文件,很多程序都使用這種格式的文本,比如Microsoft Excel。CSV文件十多條記錄的列表,每一條記錄一行,一行內(nèi)值與值之間逗號(hào)分割,如果一個(gè)值內(nèi)也包含逗號(hào)這個(gè)值必須用雙引號(hào)引起來(lái),如果值內(nèi)還包含雙引號(hào),需使用雙引號(hào)轉(zhuǎn)義雙引號(hào)(就是兩個(gè)雙引號(hào)表示一個(gè)),看例子,下面的數(shù)組:
{'a b', 'a,b', 'a,"b"c', 'hello "world"!', }
可以看作為:
a b,"a,b"," a,""b""c", hello "world"!,
將一個(gè)字符串?dāng)?shù)組轉(zhuǎn)換為CSV格式的文件是非常容易的。我們要做的只是使用逗號(hào)將所有的字符串連接起來(lái):
function toCSV (t)
local s = ""
for _,p in pairs(t) do
s = s .. "," .. escapeCSV(p)
end
return string.sub(s, 2) -- remove first comma
end
如果一個(gè)字符串包含逗號(hào)活著引號(hào)在里面,我們需要使用引號(hào)將這個(gè)字符串引起來(lái),并轉(zhuǎn)義原始的引號(hào):
function escapeCSV (s)
if string.find(s, '[,"]') then
s = '"' .. string.gsub(s, '"', '""') .. '"'
end
return s
end
將CSV文件內(nèi)容存放到一個(gè)數(shù)組中稍微有點(diǎn)難度,因?yàn)槲覀儽仨殔^(qū)分出位于引號(hào)中間的逗號(hào)和分割域的逗號(hào)。我們可以設(shè)法轉(zhuǎn)義位于引號(hào)中間的逗號(hào),然而并不是所有的引號(hào)都是作為引號(hào)存在,只有在逗號(hào)之后的引號(hào)才是一對(duì)引號(hào)的開(kāi)始的那一個(gè)。只有不在引號(hào)中間的逗號(hào)才是真正的逗號(hào)。這里面有太多的細(xì)節(jié)需要注意,比如,兩個(gè)引號(hào)可能表示單個(gè)引號(hào),可能表示兩個(gè)引號(hào),還有可能表示空:
"hello""hello", "",""
這個(gè)例子中,第一個(gè)域是字符串 "hello"hello",第二個(gè)域是字符串 " """(也就是一個(gè)空白加兩個(gè)引號(hào)),最后一個(gè)域是一個(gè)空串。
我們可以多次調(diào)用gsub來(lái)處理這些情況,但是對(duì)于這個(gè)任務(wù)使用傳統(tǒng)的循環(huán)(在每個(gè)域上循環(huán))來(lái)處理更有效。循環(huán)體的主要任務(wù)是查找下一個(gè)逗號(hào);并將域的內(nèi)容存放到一個(gè)表中。對(duì)于每一個(gè)域,我們循環(huán)查找封閉的引號(hào)。循環(huán)內(nèi)使用模式 ' "("?) ' 來(lái)查找一個(gè)域的封閉的引號(hào):如果一個(gè)引號(hào)后跟著一個(gè)引號(hào),第二個(gè)引號(hào)將被捕獲并賦給一個(gè)變量c,意味著這仍然不是一個(gè)封閉的引號(hào)。
function fromCSV (s)
s = s .. ',' -- ending comma
local t = {} -- table to collect fields
local fieldstart = 1
repeat
-- next field is quoted? (start with `"'?)
if string.find(s, '^"', fieldstart) then
local a, c
local i = fieldstart
repeat
-- find closing quote
a, i, c = string.find(s, '"("?)', i+1)
until c ~= '"' -- quote not followed by quote?
if not i then error('unmatched "') end
local f = string.sub(s, fieldstart+1, i-1)
table.insert(t, (string.gsub(f, '""', '"')))
fieldstart = string.find(s, ',', i) + 1
else -- unquoted; find next comma
local nexti = string.find(s, ',', fieldstart)
table.insert(t, string.sub(s, fieldstart,
nexti-1))
fieldstart = nexti + 1
end
until fieldstart > string.len(s)
return t
end
t = fromCSV('"hello "" hello", "",""')
for i, s in ipairs(t) do print(i, s) end
--> 1 hello " hello
--> 2 ""
--> 3
相關(guān)文章
Lua字符串庫(kù)中的幾個(gè)重點(diǎn)函數(shù)介紹
這篇文章主要介紹了Lua字符串庫(kù)中的幾個(gè)重點(diǎn)函數(shù)介紹,本文講解了幾個(gè)最常用的強(qiáng)大的字符串函數(shù)find、match、gsub、gmatch,需要的朋友可以參考下2014-09-09實(shí)現(xiàn)Lua中數(shù)據(jù)類型的源碼分享
在Lua中有8種基礎(chǔ)類型,像其他動(dòng)態(tài)語(yǔ)言一樣,在語(yǔ)言中沒(méi)有類型定義的語(yǔ)法,每個(gè)值都攜帶了它自身的類型信息。下面我們就來(lái)嘗試通過(guò)Lua 5.2.1的源碼來(lái)看類型的實(shí)現(xiàn)2015-04-04Lua中pairs與ipairs的區(qū)別總結(jié)
這篇文章主要給大家介紹了關(guān)于Lua中pairs與ipairs區(qū)別的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09使用Lua作為C語(yǔ)言項(xiàng)目的配置文件實(shí)例
這篇文章主要介紹了使用Lua作為C語(yǔ)言項(xiàng)目的配置文件實(shí)例,本文用Lua創(chuàng)建了一個(gè)配置文件,然后在C言語(yǔ)中解析它,需要的朋友可以參考下2015-04-04Lua檢測(cè)數(shù)組(tabble)中是否包含某個(gè)值
這篇文章主要介紹了Lua檢測(cè)數(shù)組(tabble)中是否包含某個(gè)值以及l(fā)ua 判斷一個(gè)字符是否存在某個(gè)數(shù)組兩個(gè)方法,需要的朋友可以參考下2015-05-05Lua返回一個(gè)Closures函數(shù)實(shí)例
這篇文章主要介紹了Lua返回一個(gè)Closures函數(shù)實(shí)例,本文直接給出代碼實(shí)例,需要的朋友可以參考下2015-04-04openresty中使用lua-nginx創(chuàng)建socket實(shí)例
這篇文章主要介紹了openresty中使用lua-nginx創(chuàng)建socket實(shí)例,本文直接給出代碼實(shí)例和運(yùn)行效果,需要的朋友可以參考下2015-04-04