自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

關(guān)于Lua模式匹配學(xué)習(xí)教程

移動(dòng)開(kāi)發(fā) iOS
Lua并不使用POSIX規(guī)范的正則表達(dá)式[4](也寫作regexp)來(lái)進(jìn)行模式匹配。主要的原因出于程序大小方面的考慮:實(shí)現(xiàn)一個(gè)典型的符合POSIX標(biāo)準(zhǔn)的regexp大概需要4000行代碼,這比整個(gè)Lua標(biāo)準(zhǔn)庫(kù)加在一起都大。

關(guān)于Lua模式匹配學(xué)習(xí)是本文要介紹的內(nèi)容,主要是來(lái)學(xué)習(xí)Lua模式匹配的問(wèn)題,具體內(nèi)容的實(shí)現(xiàn)來(lái)卡本文詳解。模式匹配函:

在string庫(kù)中功能***大的函數(shù)是:

  1. string.find(字符串查找)  
  2. string.gsub(全局字符串替換)  
  3. string.gfind(全局字符串查找)  
  4. string.gmatch(返回查找到字符串的迭代器) 

這些函數(shù)都是基于模式匹配的。與其他腳本語(yǔ)言不同的是,Lua并不使用POSIX規(guī)范的正則表達(dá)式[4](也寫作regexp)來(lái)進(jìn)行模式匹配。主要的原因出于程序大小方面的考慮:實(shí)現(xiàn)一個(gè)典型的符合POSIX標(biāo)準(zhǔn)的regexp大概需要4000行代碼,這比整個(gè)Lua標(biāo)準(zhǔn)庫(kù)加在一起都大。權(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)的功能。

  1. string.gmatch(str, pattern)       

這是一個(gè)返回迭代器的函數(shù). 實(shí)際的用例如下:

  1. s = "hello world from Lua" 
  2. for w in string.gmatch(s, "%a+") do  
  3.  print(w)  
  4. end 

這里是一個(gè)捕獲并將配對(duì)字符分別存到不同變量的例子:

  1. t = {}  
  2. s = "from=world, to=Lua" 
  3. for k, v in string.gmatch(s, "(%w+)=(%w+)") do  
  4.  t[k]=v  
  5. end  
  6. for k, v in pairs(t) do  
  7.  print(k, v)  
  8. end  
  9. string.gsub(str, pattern, repl, n) 

string.gsub()函數(shù)根據(jù)給定的配對(duì)表達(dá)式對(duì)源字符串str進(jìn)行配對(duì), 同時(shí)返回源字符串的一個(gè)副本, 該副本中成功配對(duì)的所有子字符串都將被替換. 函數(shù)還將返回成功配對(duì)的次數(shù).實(shí)際的替換行為由repl參數(shù)的類型決定:

當(dāng)repl為字符串時(shí), 所有成功配對(duì)的子字符串均會(huì)被替換成指定的repl字串.
當(dāng)repl為table時(shí), 對(duì)每個(gè)成功配對(duì)的子字符串, 函數(shù)均會(huì)試圖尋找以其為key值的table中的元素, 并返回該元素. 如果該配對(duì)包含任何捕獲信息, 則以編號(hào)為1號(hào)的捕獲作為key值進(jìn)行查找.
當(dāng)repl為函數(shù)時(shí), 每個(gè)成功配對(duì)的子字符串均會(huì)作為參數(shù)被傳入到該函數(shù)中去.
在repl是table或函數(shù)時(shí), 如果該table或函數(shù)返回了字串或數(shù)字的值, 這個(gè)值依然會(huì)被用于替換副本字串中的配對(duì)子字串. 如果該table/函數(shù)返回的值為空, 將不發(fā)生替換.

n參數(shù)可選, 當(dāng)它被指定時(shí), string.gsub()函數(shù)只對(duì)源字符串中的前n個(gè)成功配對(duì)的成員進(jìn)行操作.

以下是幾個(gè)例子:

  1. > print(string.gsub("hello world", "(%w+)", "%1 %1"))  
  2. hello hello world world 2  
  3. > print(string.gsub("hello Lua", "(%w+)%s*(%w+)", "%2 %1"))  
  4. Lua hello 1  
  5. > string.gsub("hello world", "%w+", print)  
  6. hello world 2  
  7. > lookupTable = {["hello"] = "hola", ["world"] = "mundo"}  
  8. > print(string.gsub("hello world", "(%w+)", lookupTable))  
  9. hola mundo 2  
  10. string.match(str, pattern, init)  

string.match()只尋找源字串str中的***個(gè)配對(duì). 參數(shù)init可選, 指定搜尋過(guò)程的起點(diǎn), 默認(rèn)為1.

在成功配對(duì)時(shí), 函數(shù)將返回配對(duì)表達(dá)式中的所有捕獲結(jié)果; 如果沒(méi)有設(shè)置捕獲標(biāo)記, 則返回整個(gè)配對(duì)字符串. 當(dāng)沒(méi)有成功的配對(duì)時(shí), 返回nil.

  1. string.match("abcdaef", "a")  
  2. -> a  
  3. string.reverse(str) 

返回一個(gè)字符串的倒序排列

  1. string.reverse("abcde")  
  2. ->edcba  
  3. string.dump(function) 

返回指定函數(shù)的二進(jìn)制代碼(函數(shù)必須是一個(gè)Lua函數(shù),并且沒(méi)有上值)

  1. string.find(str, pattern, init, plain)  

string.find的基本應(yīng)用就是用來(lái)在目標(biāo)串(subject string)內(nèi)搜索匹配指定的模式的串。函數(shù)如果找到匹配的串返回他的位置,否則返回nil.最簡(jiǎn)單的模式就是一個(gè)單詞,僅僅匹配單詞本身。比如,模式'hello'僅僅匹配目標(biāo)串中的"hello"。當(dāng)查找到模式的時(shí)候,函數(shù)返回兩個(gè)值:匹配串開(kāi)始索引和結(jié)束索引。

  1. s = "hello world" 
  2. string.find(s, "hello")    --> 1    5  
  3. string.find(s, "world")    --> 7    11  
  4. string.find(s, "l")        --> 3    3  
  5. string.find(s, "lll")      --> nil 

string.find函數(shù)第三個(gè)參數(shù)是可選的:標(biāo)示目標(biāo)串中搜索的起始位置。當(dāng)我們想查找目標(biāo)串中所有匹配的子串的時(shí)候,這個(gè)選項(xiàng)非常有用。我們可以不斷的循環(huán)搜索,每一次從前一次匹配的結(jié)束位置開(kāi)始。下面看一個(gè)例子,下面的代碼用一個(gè)字符串中所有的新行構(gòu)造一個(gè)表:

  1. local t = {}      -- 存放回車符的位置  
  2. local i = 0 
  3. while true do  
  4.     i = string.find(s, "\n", i+1)  -- 查找下一行  
  5.     if i == nil then break end  
  6.     table.insert(t, i)  
  7. end  
  8. string.sub(str,sPos,ePos) 

string.gsub的功能是截取字符串,他從指定起始位置截取一個(gè)字符串。string.sub可以利用string.find返回的值截取匹配的子串。

對(duì)簡(jiǎn)單模式而言,匹配的就是其本身

  1. s = "hello world" 
  2. local i, j = string.find(s, "hello")    --> 1    5  
  3. string.sub(s, i, j)        --> hello  
  4. string.gsub(str, sourcestr, desstr) 

string.gsub的基本作用是用來(lái)查找匹配模式的串,并將使用替換串其替換掉:

string.gsub函數(shù)有三個(gè)參數(shù):目標(biāo)串,模式串,替換串。

  1. s = string.gsub("Lua is cute", "cute", "great")  
  2. print(s)      --> Lua is great  
  3. s = string.gsub("all lii", "l", "x")  
  4. print(s)      --> axx xii  
  5. s = string.gsub("Lua is great", "perl", "tcl")  
  6. print(s)      --> Lua is great 

第四個(gè)參數(shù)是可選的,用來(lái)限制替換的范圍:

  1. s = string.gsub("all lii", "l", "x", 1)  
  2. print(s)          --> axl lii  
  3. s = string.gsub("all lii", "l", "x", 2)  
  4. print(s)          --> axx lii 

string.gsub的第二個(gè)返回值表示他進(jìn)行替換操作的次數(shù)。例如,下面代碼涌來(lái)計(jì)算一個(gè)字符串中空格出現(xiàn)的次數(shù):

  1. _, count = string.gsub(str, " ", " ") 

(注意,_ 只是一個(gè)啞元變量)

模式

你還可以在模式串中使用字符類。字符類指可以匹配一個(gè)特定字符集合內(nèi)任何字符的模式項(xiàng)。比如,字符類%d匹配任意數(shù)字。所以你可以使用模式串'%d%d/%d%d/%d%d%d%d'搜索dd/mm/yyyy格式的日期:

  1. s = "Deadline is 30/05/1999, firm" 
  2. date = "%d%d/%d%d/%d%d%d%d" 
  3. print(string.sub(s, string.find(s, date)))    --> 30/05/1999 

下面的表列出了Lua支持的所有字符類:

單個(gè)字符(除^$()%.[]*+-?外): 與該字符自身配對(duì)

  1. .(點(diǎn)): 與任何字符配對(duì)  
  2.  
  3. %a: 與任何字母配對(duì)  
  4. %c: 與任何控制符配對(duì)(例如\n)  
  5. %d: 與任何數(shù)字配對(duì)  
  6. %l: 與任何小寫字母配對(duì)  
  7. %p: 與任何標(biāo)點(diǎn)(punctuation)配對(duì)  
  8. %s: 與空白字符配對(duì)  
  9. %u: 與任何大寫字母配對(duì)  
  10. %w: 與任何字母/數(shù)字配對(duì)  
  11. %x: 與任何十六進(jìn)制數(shù)配對(duì)  
  12. %z: 與任何代表0的字符配對(duì)  
  13. %x(此處x是非字母非數(shù)字字符): 與字符x配對(duì). 主要用來(lái)處理表達(dá)式中有功能的字符(^$()%.[]*+-?)的配對(duì)問(wèn)題, 例如%%與%配對(duì) 

[數(shù)個(gè)字符類]: 與任何[]中包含的字符類配對(duì). 例如[%w_]與任何字母/數(shù)字, 或下劃線符號(hào)(_)配對(duì)

[^數(shù)個(gè)字符類]: 與任何不包含在[]中的字符類配對(duì). 例如[^%s]與任何非空白字符配對(duì)

當(dāng)上述的字符類用大寫書(shū)寫時(shí), 表示與非此字符類的任何字符配對(duì). 例如, %S表示與任何非空白字符配對(duì).例如,'%A'非字母的字符

  1. print(string.gsub("hello, up-down!", "%A", "."))  
  2.     --> hello..up.down. 4 

(數(shù)字4不是字符串結(jié)果的一部分,他是gsub返回的第二個(gè)結(jié)果,代表發(fā)生替換的次數(shù)。下面其他的關(guān)于打印gsub結(jié)果的例子中將會(huì)忽略這個(gè)數(shù)值。)在模式匹配中有一些特殊字符,他們有特殊的意義,Lua中的特殊字符如下:

  1. ( ) . % + - * ? [ ^ $ 

'%' 用作特殊字符的轉(zhuǎn)義字符,因此 '%.' 匹配點(diǎn);'%%' 匹配字符 '%'。轉(zhuǎn)義字符 '%'不僅可以用來(lái)轉(zhuǎn)義特殊字符,還可以用于所有的非字母的字符。當(dāng)對(duì)一個(gè)字符有疑問(wèn)的時(shí)候,為安全起見(jiàn)請(qǐng)使用轉(zhuǎn)義字符轉(zhuǎn)義他。

對(duì)Lua而言,模式串就是普通的字符串。他們和其他的字符串沒(méi)有區(qū)別,也不會(huì)受到特殊對(duì)待。只有他們被用作模式串用于函數(shù)的時(shí)候,'%' 才作為轉(zhuǎn)義字符。所以,如果你需要在一個(gè)模式串內(nèi)放置引號(hào)的話,你必須使用在其他的字符串中放置引號(hào)的方法來(lái)處理,使用 '\' 轉(zhuǎn)義引號(hào),'\' 是Lua的轉(zhuǎn)義符。你可以使用方括號(hào)將字符類或者字符括起來(lái)創(chuàng)建自己的字符類(譯者:Lua稱之為char-set,就是指?jìng)鹘y(tǒng)正則表達(dá)式概念中的括號(hào)表達(dá)式)。比如,'[%w_]' 將匹配字母數(shù)字和下劃線,'[01]' 匹配二進(jìn)制數(shù)字,'[%[%]]' 匹配一對(duì)方括號(hào)。下面的例子統(tǒng)計(jì)文本中元音字母出現(xiàn)的次數(shù):

  1. _, nvow = string.gsub(text, "[AEIOUaeiou]", "") 

在char-set中可以使用范圍表示字符的集合,***個(gè)字符和***一個(gè)字符之間用連字符連接表示這兩個(gè)字符之間范圍內(nèi)的字符集合。大部分的常用字符范圍都已經(jīng)預(yù)定義好了,所以一般你不需要自己定義字符的集合。比如,'%d' 表示 '[0-9]';'%x' 表示 '[0-9a-fA-F]'。然而,如果你想查找八進(jìn)制數(shù),你可能更喜歡使用 '[0-7]' 而不是 '[01234567]'。你可以在字符集(char-set)的開(kāi)始處使用 '^' 表示其補(bǔ)集:'[^0-7]' 匹配任何不是八進(jìn)制數(shù)字的字符;'[^\n]' 匹配任何非換行符戶的字符。記住,可以使用大寫的字符類表示其補(bǔ)集:'%S' 比 '[^%s]' 要簡(jiǎn)短些。

Lua的字符類依賴于本地環(huán)境,所以 '[a-z]' 可能與 '%l' 表示的字符集不同。在一般情況下,后者包括 'ç' 和 'ã',而前者沒(méi)有。應(yīng)該盡可能的使用后者來(lái)表示字母,除非出于某些特殊考慮,因?yàn)楹笳吒?jiǎn)單、方便、更高效。

可以使用修飾符來(lái)修飾模式增強(qiáng)模式的表達(dá)能力,Lua中的模式修飾符有四個(gè):

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

'+',匹配一個(gè)或多個(gè)字符,總是進(jìn)行最長(zhǎng)的匹配。比如,模式串 '%a+' 匹配一個(gè)或多個(gè)字母或者一個(gè)單詞:

  1. print(string.gsub("one, and two; and three", "%a+", "word"))  
  2.     --> word, word word; word word 

'%d+' 匹配一個(gè)或多個(gè)數(shù)字(整數(shù)):

  1. i, j = string.find("the number 1298 is even", "%d+")  
  2. print(i,j)    --> 12  15 

'*' 與 '+' 類似,但是他匹配一個(gè)字符0次或多次出現(xiàn).一個(gè)典型的應(yīng)用是匹配空白。比如,為了匹配一對(duì)圓括號(hào)()或者括號(hào)之間的空白,可以使用 '%(%s*%)'。( '%s*' 用來(lái)匹配0個(gè)或多個(gè)空白。由于圓括號(hào)在模式中有特殊的含義,所以我們必須使用 '%' 轉(zhuǎn)義他。)再看一個(gè)例子,'[_%a][_%w]*' 匹配Lua程序中的標(biāo)示符:字母或者下劃線開(kāi)頭的字母下劃線數(shù)字序列。

'-' 與 '*' 一樣,都匹配一個(gè)字符的0次或多次出現(xiàn),但是他進(jìn)行的是最短匹配。某些時(shí)候這兩個(gè)用起來(lái)沒(méi)有區(qū)別,但有些時(shí)候結(jié)果將截然不同。比如,如果你使用模式 '[_%a][_%w]-' 來(lái)查找標(biāo)示符,你將只能找到***個(gè)字母,因?yàn)?'[_%w]-' 永遠(yuǎn)匹配空。另一方面,假定你想查找C程序中的注釋,很多人可能使用 '/%*.*%*/'(也就是說(shuō) "/*" 后面跟著任意多個(gè)字符,然后跟著 "*/" )。然而,由于 '.*' 進(jìn)行的是最長(zhǎng)匹配,這個(gè)模式將匹配程序中***個(gè) "/*" 和***一個(gè) "*/" 之間所有部分:

  1. test = "int x; /* x */ int y; /* y */" 
  2. print(string.gsub(test, "/%*.*%*/", "<COMMENT>"))  
  3.     --> int x; <COMMENT> 

然而模式 '.-' 進(jìn)行的是最短匹配,她會(huì)匹配 "/*" 開(kāi)始到***個(gè) "*/" 之前的部分:

  1. test = "int x; /* x */ int y; /* y */" 
  2. print(string.gsub(test, "/%*.-%*/", "<COMMENT>"))  
  3.     --> int x; <COMMENT> int y; <COMMENT> 

'?' 匹配一個(gè)字符0次或1次。舉個(gè)例子,假定我們想在一段文本內(nèi)查找一個(gè)整數(shù),整數(shù)可能帶有正負(fù)號(hào)。模式 '[+-]?%d+' 符合我們的要求,它可以匹配像 "-12"、"23" 和 "+1009" 等數(shù)字。'[+-]' 是一個(gè)匹配 '+' 或者 '-' 的字符類;接下來(lái)的 '?' 意思是匹配前面的字符類0次或者1次。

與其他系統(tǒng)的模式不同的是,Lua中的修飾符不能用字符類;不能將模式分組然后使用修飾符作用這個(gè)分組。比如,沒(méi)有一個(gè)模式可以匹配一個(gè)可選的單詞(除非這個(gè)單詞只有一個(gè)字母)。下面我將看到,通常你可以使用一些高級(jí)技術(shù)繞開(kāi)這個(gè)限制。

以 '^' 開(kāi)頭的模式只匹配目標(biāo)串的開(kāi)始部分,相似的,以 '$' 結(jié)尾的模式只匹配目標(biāo)串的結(jié)尾部分。這不僅可以用來(lái)限制你要查找的模式,還可以定位(anchor)模式。比如:

  1. if string.find(s, "^%d") then ... 

檢查字符串s是否以數(shù)字開(kāi)頭,而

  1. if string.find(s, "^[+-]?%d+$") then ... 

檢查字符串s是否是一個(gè)整數(shù)。

'%b' 用來(lái)匹配對(duì)稱的字符。常寫為 '%bxy' ,x和y是任意兩個(gè)不同的字符;x作為匹配的開(kāi)始,y作為匹配的結(jié)束。比如,'%b()' 匹配以 '(' 開(kāi)始,以 ')' 結(jié)束的字符串:

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

常用的這種模式有:'%b()' ,'%b[]','%b%{%}' 和 '%b<>'。你也可以使用任何字符作為分隔符。

小結(jié):關(guān)于Lua模式匹配學(xué)習(xí)教程的內(nèi)容介紹完了,希望通過(guò)本文的學(xué)習(xí)能對(duì)你有所幫助!

責(zé)任編輯:zhaolei 來(lái)源: 博客園
相關(guān)推薦

2011-08-24 14:14:13

LUA環(huán)境 配置

2011-08-23 16:37:05

Lua數(shù)學(xué)庫(kù)

2011-08-24 15:42:38

LUA源代碼

2011-08-25 15:41:42

Lua源碼

2011-08-24 15:34:44

MinGWLua環(huán)境配置

2011-08-24 17:09:35

LUA閉包函數(shù)

2011-08-24 11:08:09

Lua

2011-08-25 16:20:33

Lua腳本變量

2011-08-24 13:27:07

Lua 游戲C接口腳本

2011-08-23 17:06:03

2011-08-23 16:48:41

Lua 5.1API 函數(shù)

2011-08-23 13:54:10

LUA全局變量

2011-08-23 15:57:21

Lua元表元方法

2011-08-23 13:27:46

Luaglobal變量

2010-07-26 10:51:26

Perl模式匹配

2011-08-24 11:03:33

LUA環(huán)境 安裝

2011-08-25 17:01:50

LUA網(wǎng)游游戲

2011-08-23 17:33:08

LuaMetatable

2011-08-23 10:29:13

LuaPlayer

2010-07-21 13:27:06

Perl模式匹配
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)