Lua 語言的模式匹配 正規表示式

2021-09-02 08:59:02 字數 3155 閱讀 6075

lua 的模式匹配不使用posix規範的正規表示式(也寫做regexp)來進行模式匹配。主要的原因出於程式大小方面的考慮:實現乙個典型的符合posix標準的regexp大概需要4000行**,這比整個lua標準庫加在一起都大。權衡之下,lua中的模式匹配的實現只用了500行**,當然這意味著不可能實現posix所規範的所有更能。然而,lua中的模式匹配功能是很強大的,並且包含了一些使用標準posix模式匹配不容易實現的功能。

lua支援的所有字元類:

. 任意字元

%a 字母

%c 控制字元

%d 數字

%l  小寫字母

%p 標點字元

% s 空白符

%u 大寫字元

%w 字母和數字

%x 十六進製制數字

%z 代表0的字元

上面字元類的大寫形式表示小寫所代表的集合的補集。例如,'%a'非字母的字元:

print(string.gsub("hello, up-down!", "%a", "."))

--> hello..up.down. 4

例子:s = "deadline is 30/05/1999, firm"

date = "%d%d/%d%d/%d%d%d%d"

print(string.sub(s, string.find(s, date))) --> 30/05/1999

在模式匹配中有一些特殊字元,他們有特殊的意義,lua中的特殊字元如下:

'%' 用作特殊字元的轉義字元,因此 '%.' 匹配點;'%%' 匹配字元 '%'。轉義字元 '%'不僅可以用來轉義特殊字元,還可以用於所有的非字母的字元。當對乙個字元有疑問的時候,為安全起見請使用轉義字元轉義他。

對lua而言,模式串就是普通的字串。他們和其他的字串沒有區別,也不會受到特殊對待。只有他們被用作模式串用於函式的時候,'%' 才作為轉義字元。所以,如果你需要在乙個模式串內放置引號的話,你必須使用在其他的字串中放置引號的方法來處理,使用 '/' 轉義引號,'/' 是lua的轉義符。

你可以使用方括號將字元類或者字元括起來建立自己的字元類(譯者:lua稱之為char-set,就是指傳統正規表示式概念中的括號表示式)。比如,'[%w_]' 將匹配字母數字和下劃線,'[01]' 匹配二進位制數字,'[%[%]]' 匹配一對方括號。

下面的例子統計文字中母音字母出現的次數:

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

可以使用修飾符來修飾模式增強模式的表達能力,lua中的模式修飾符有四個:

+ 匹配前一字元1次或多次

* 匹配前一字元0次或多次

- 匹配前一字元0次或多次

? 匹配前一字元0次或1次

'+',匹配乙個或多個字元,總是進行最長的匹配。比如,模式串 '%a+' 匹配乙個或多個字母或者乙個單詞:

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

--> word, word word; word word

'%d+' 匹配乙個或多個數字(整數):

i, j = string.find("the number 1298 is even", "%d+")

print(i,j) --> 12 15

'*' 與 '+' 類似,但是他匹配乙個字元0次或多次出現.乙個典型的應用是匹配空白。

比如,為了匹配一對圓括號()或者括號之間的空白,可以使用 '%(%s*%)'。( '%s*' 用來匹配0個或多個空白。由於圓括號在模式中有特殊的含義,所以我們必須使用 '%' 轉義他。)再看乙個例子,'[_%a][_%w]*' 匹配lua程式中的標示符:字母或者下劃線開頭的字母下劃線數字序列。

'-' 與 '*' 一樣,都匹配乙個字元的0次或多次出現,但是他進行的是最短匹配。某些時候這兩個用起來沒有區別,但有些時候結果將截然不同。比如,如果你使用模式 '[_%a][_%w]-' 來查詢標示符,你將只能找到第乙個字母,因為 '[_%w]-' 永遠匹配空。另一方面,假定你想查詢c程式中的注釋,很多人可能使用 '/%*.*%*/'(也就是說 "/*" 後面跟著任意多個字元,然後跟著 "*/" )。然而,由於 '.*' 進行的是最長匹配,這個模式將匹配程式中第乙個 "/*" 和最後乙個 "*/" 之間所有部分:

test = "int x; /* x */ int y; /* y */"

print(string.gsub(test, "/%*.*%*/", ""))

--> int x;

然而模式 '.-' 進行的是最短匹配,她會匹配 "/*" 開始到第乙個 "*/" 之前的部分:

test = "int x; /* x */ int y; /* y */"

print(string.gsub(test, "/%*.-%*/", ""))

--> int x; int y;

'?' 匹配乙個字元0次或1次。舉個例子,假定我們想在一段文字內查詢乙個整數,整數可能帶有正負號。模式 '[+-]?%d+' 符合我們的要求,它可以匹配像 "-12"、"23" 和 "+1009" 等數字。'[+-]' 是乙個匹配 '+' 或者 '-' 的字元類;接下來的 '?' 意思是匹配前面的字元類0次或者1次。

與其他系統的模式不同的是,lua中的修飾符不能用字元類;不能將模式分組然後使用修飾符作用這個分組。比如,沒有乙個模式可以匹配乙個可選的單詞(除非這個單詞只有乙個字母)。下面我將看到,通常你可以使用一些高階技術繞開這個限制。

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

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

檢查字串s是否以數字開頭,而

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

檢查字串s是否是乙個整數。

'%b' 用來匹配對稱的字元。常寫為 '%bxy' ,x和y是任意兩個不同的字元;x作為匹配的開始,y作為匹配的結束。比如,'%b()' 匹配以 '(' 開始,以 ')' 結束的字串:

print(string.gsub("a (enclosed (in) parentheses) line",

"%b()", ""))

--> a line

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

Lua正規表示式

正規表示式作為一種通用的算式,大量用於文字處理邏輯中,其主要好處是速度能夠達到極致,而且 量通常會非常少,本篇主要介紹lua中的正則使用,由於這樣的文章網上隨處都可以搜到,而且不乏整理的不錯的,這裡就不想再重新做這件事情。正規表示式主要處理匹配問題,即通過給定語義萬用字元串,返回匹配成功的字串列表。...

lua正規表示式

一樣,都匹配乙個字元的0次或多次出現,但是他進行的是最短匹配。某些時候這兩個用起來沒有區別,但有些時候結果將截然不同。比如,如果你使用模式 a w 來查詢標示符,你將只能找到第乙個字母,因為 w 永遠匹配空。另一方面,假定你想查詢c程式中的注釋,很多人可能使用 也就是說 後面跟著任意多個字元,然後跟...

lua 正規表示式

點 與任何字元配對 a 與任何字母配對 c 與任何控制符配對 例如 n d 與任何數字配對 l 與任何小寫字母配對 p 與任何標點 punctuation 配對 s 與空白字元配對 u 與任何大寫字母配對 w 與任何字母 數字配對 x 與任何十六進製制數配對 z 與任何代表0的字元配對 x 此處x是...