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

詳解LUA中關(guān)于正則表達(dá)式

移動(dòng)開發(fā) iOS
Lua并不使用POSIX規(guī)范的正則表達(dá)式(也寫作regexp)來進(jìn)行模式匹配(譯者:POSIX是unix的工業(yè)標(biāo)準(zhǔn),regexp最初來源于unix,POSIX對(duì)regexp也作了規(guī)范)。

LUA中關(guān)于正則表達(dá)式是本文要介紹的內(nèi)容,LUA中的正則表達(dá)式跟傳統(tǒng)的不一樣,作者特把手冊(cè)里一段關(guān)于正則說明抄下來,做個(gè)記錄,這些只是簡(jiǎn)單的說明一下LUA中正則的則規(guī),對(duì)于后面的高級(jí)應(yīng)用以后再慢慢研究,紅色部分為LUA中常用正則表達(dá)式說明 . ...模式匹配函數(shù) 

在string庫中功能最強(qiáng)大的函數(shù)是:string.find (字符串查找), string.gsub (全局字符串替換), and string.gfind (全局字符串查找). 這些函數(shù)都是基于模式匹配的。

與其他腳本語言不同的是,Lua并不使用POSIX規(guī)范的正則表達(dá)式(也寫作regexp)來進(jìn)行模式匹配(譯者:POSIX是unix的工業(yè)標(biāo)準(zhǔn),regexp最初來源于unix,POSIX對(duì)regexp也作了規(guī)范)。主要的原因出于程序大小方面的考慮:實(shí)現(xiàn)一個(gè)典型的符合POSIX標(biāo)準(zhǔn)的regexp大概需要4000行代碼,這比整個(gè)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)的功能。

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

  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 

例子中,匹配成功的時(shí)候,string.sub利用string.find返回的值截取匹配的子串。 (對(duì)簡(jiǎn)單模式而言,匹配的就是其本身。)

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

  1. local t = {}                   -- table to store the indices  
  2. local i = 0 
  3. while true do  
  4.   i = string.find(s, "\n", i+1)    -- find 'next' newline  
  5.   if i == nil then break end  
  6.   table.insert(t, i)  
  7. end 

后面我們還會(huì)看到可以使用string.gfind迭代子來簡(jiǎn)化上面這個(gè)循環(huán)。

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ù)是可選的,用來限制替換的范圍:

  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ù)。例如,下面代碼涌來計(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支持的所有字符類:

  1. .        任意字符  
  2.  %a        字母  
  3.  %c        控制字符  
  4.  %d        數(shù)字  
  5.  %l        小寫字母  
  6.  %p        標(biāo)點(diǎn)字符  
  7.  %s        空白符  
  8.  %u        大寫字母  
  9.  %w        字母和數(shù)字  
  10.  %x        十六進(jìn)制數(shù)字  
  11.  %z        代表0的字符 

上面字符類的大寫形式表示小寫所代表的集合的補(bǔ)集。例如, '%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)義字符`%′不僅可以用來轉(zhuǎn)義特殊字符,還可以用于所有的非字母的字符。當(dāng)對(duì)一個(gè)字符有疑問的時(shí)候,為安全起見請(qǐng)使用轉(zhuǎn)義字符轉(zhuǎn)義他。

對(duì)Lua而言,模式串就是普通的字符串。他們和其他的字符串沒有區(qū)別,也不會(huì)受到特殊對(duì)待。只有他們被用作模式串用于函數(shù)的時(shí)候,`%′才作為轉(zhuǎn)義字符。所以,如果你需要在一個(gè)模式串內(nèi)放置引號(hào)的話,你必須使用在其他的字符串中放置引號(hào)的方法來處理,使用`\′轉(zhuǎn)義引號(hào),`\′是Lua的轉(zhuǎn)義符。你可以使用方括號(hào)將字符類或者字符括起來創(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)的開始處使用 `^′ 表示其補(bǔ)集: '[^0-7]' 匹配任何不是八進(jìn)制數(shù)字的字符; '[^\n]' 匹配任何非換行符戶的字符。記住,可以使用大寫的字符類表示其補(bǔ)集: '%S'比'[^%s]'要簡(jiǎn)短些.

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

可以使用修飾符來修飾模式增強(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)()或者( )之間的空白,可以使用'%(%s*%)'. ( '%s*'用來匹配0個(gè)或多個(gè)空白. 由于圓括號(hào)在模式中有特殊的含義,所以我們必須使用`%′轉(zhuǎn)義他.) 再看一個(gè)例子,'[_%a][_%w]*'匹配Lua程序中的標(biāo)示符:字母或者下劃線開頭的字母下劃線數(shù)字序列。

`-′與`*′一樣,都匹配一個(gè)字符的0次或多次出現(xiàn),但是他進(jìn)行的是最短匹配。某些時(shí)候這兩個(gè)用起來沒有區(qū)別,但有些時(shí)候結(jié)果將截然不同。比如,如果你使用模式'[_%a][_%w]-'來查找標(biāo)示符,你將只能找到第一個(gè)字母,因?yàn)?[_%w]-'永遠(yuǎn)匹配空。另一方面,假定你想查找C程序中的注釋,很多人可能使用 '/%*.*%*/' (也就是說 "/*" 后面跟著任意多個(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ì)匹配"/*"開始到第一個(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è)匹配`+′或者 `-′的字符類;接下來的 `?′意思是匹配前面的字符類0次或者1次.

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

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

  1. if string.find(s, "^%d") then ...  
  2. 符串s是否以數(shù)字開頭,而   
  3. if string.find(s, "^[+-]?%d+$") then ... 

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

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

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

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

作者提出問題的原帖:

由于看到TheoryCraft這個(gè)不錯(cuò)的插件,查找網(wǎng)站發(fā)現(xiàn)一年來竟然沒人漢化,同時(shí)為了學(xué)習(xí),決定自己動(dòng)手試試,但在看代碼時(shí)遇見一些問題,特請(qǐng)教各位大大

首先我貼一段插件中的代碼來分析:

  1. TheoryCraft_MeleeComboEnergyConverter = "into (.-) additional" 
  2. TheoryCraft_MeleeComboReader = "(%d+) point(.-): (%d+)%-(%d+) damage" 
  3. TheoryCraft_MeleeComboReplaceWith = "$points$ point%1: %2%-%3 damage" 

第一行中的(.-)有點(diǎn)怪,是什么意思,如果要翻譯的這句話時(shí)要如何處理,

第二行中%這個(gè)符號(hào)是否相當(dāng)于轉(zhuǎn)位符/,是不是LUA中特有的替代/

第三行中$我看正則表達(dá)式中好象是串位符,但為什么會(huì)放在第一個(gè)?

小結(jié):詳解LUA中關(guān)于正則表達(dá)式的內(nèi)容介紹完了,希望通過本文的學(xué)習(xí)能對(duì)你有所幫助!

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

2009-09-16 18:19:34

正則表達(dá)式組

2009-08-03 17:27:14

C#正則表達(dá)式

2009-09-16 17:29:30

正則表達(dá)式使用詳解

2024-10-17 17:03:43

SQL正則表達(dá)式MySQL

2009-09-16 16:22:04

正則表達(dá)式匹配

2018-09-27 15:25:08

正則表達(dá)式前端

2009-09-16 14:32:43

PHP正則表達(dá)式替換

2011-08-16 17:28:49

iPhone SDK正則表達(dá)式

2020-09-04 09:16:04

Python正則表達(dá)式虛擬機(jī)

2024-09-14 09:18:14

Python正則表達(dá)式

2009-08-20 16:23:32

C#正則表達(dá)式語法

2019-07-25 17:00:44

Python正則表達(dá)式字符串

2009-09-16 14:22:44

preg_match正

2010-03-25 18:25:36

Python正則表達(dá)式

2009-09-16 13:14:10

Ereg正則表達(dá)式

2020-11-04 09:23:57

Python

2009-06-15 17:24:59

Groovy正則表達(dá)式

2021-01-27 11:34:19

Python正則表達(dá)式字符串

2009-02-18 09:48:20

正則表達(dá)式Java教程

2011-06-02 12:34:16

正則表達(dá)式
點(diǎn)贊
收藏

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