此第一版是為 Lua 5.0 所撰寫。雖然對後續版本仍有很大的相關性,但仍有一些差異。
第四版針對 Lua 5.3,可在 Amazon 和其他書店購買。
購買本書,您也可以協助 支持 Lua 專案。
![]() |
程式設計於 Lua | ![]() |
第三部分。標準函式庫 第 20 章。字串函式庫 |
您可以使用字元類別讓模式更實用。字元類別是模式中的一個項目,可以符合特定集合中的任何字元。例如,類別 %d
符合任何數字。因此,您可以使用模式 '%d%d/%d%d/%d%d%d%d
' 來搜尋 dd/mm/yyyy
格式的日期。
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下表列出所有字元類別
. | 所有字元 |
%a | 字母 |
%c | 控制字元 |
%d | 數字 |
%l | 小寫字母 |
%p | 標點符號字元 |
%s | 空白字元 |
%u | 大寫字母 |
%w | 字母數字字元 |
%x | 十六進位數字 |
%z | 表示 0 的字元 |
任何這些類別的大寫版本代表類別的補集。例如,'%A
' 代表所有非字母字元
print(string.gsub("hello, up-down!", "%A", ".")) --> hello..up.down. 4(
4
不是結果字串的一部分。它是 gsub
的第二個結果,即替換的總數。其他會列印 gsub
結果的範例會省略這個計數。)
某些稱為特殊字元的字元在模式中使用時具有特殊意義。特殊字元為
( ) . % + - * ? [ ^ $字元 `
%
´ 可作為這些特殊字元的跳脫字元。因此,'%.
' 符合一個點;'%%
' 符合字元 `%
´ 本身。您不僅可以使用跳脫字元 `%
´ 來處理特殊字元,也可以用於所有其他非字母數字字元。有疑問時,請採取安全做法並加上跳脫字元。
對於 Lua,模式是正規字串。它們沒有特殊處理,並遵循與其他字串相同的規則。僅在函數內將它們解釋為模式,並且僅在這種情況下,`%
´ 才作為跳脫字元使用。因此,如果你需要在模式中放入引號,則必須使用與在其他字串中放入引號相同的技術;例如,你可以使用 `\
´ 跳脫引號,這是 Lua 的跳脫字元。
字元集 允許你建立自己的字元類別,將不同的類別和單一字元組合在方括號中。例如,字元集 '[%w_]
' 匹配字母數字字元和底線,字元集 '[01]
' 匹配二進位數字,而字元集 '[%[%]]
' 匹配方括號。若要計算文字中的母音數量,你可以寫
_, nvow = string.gsub(text, "[AEIOUaeiou]", "")你也可以在字元集中包含字元範圍,方法是寫出範圍的第一個和最後一個字元,並用連字號分隔。你很少需要這個功能,因為大多數有用的範圍已經預先定義;例如,'
[0-9]
' 寫成 '%d
' 時更簡單,'[0-9a-fA-F]
' 與 '%x
' 相同。但是,如果你需要找到八進位數字,則你可能更喜歡 '[0-7]
',而不是明確列舉('[01234567]
')。你可以透過在字元集開頭加上 `^
´ 來取得其補集:'[^0-7]
' 找到任何不是八進位數字的字元,而 '[^\n]
' 匹配任何與換行不同的字元。但請記住,你可以使用其大寫版本來否定簡單類別:'%S
' 比 '[^%s]
' 更簡單。
字元類別遵循 Lua 設定的目前區域設定。因此,類別 '[a-z]
' 可能與 '%l
' 不同。在適當的區域設定中,後一種形式包含 `ç
´ 和 `ã
´ 等字母。你應該始終使用後一種形式,除非你有充分的理由不這樣做:它更簡單、更具可移植性,而且效率稍高。
你可以使用重複和選用部分的修飾符讓模式更有用。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
修飾符 `*
´ 類似於 `+
´,但它也接受類別字元的零次出現。典型的用法是匹配模式部分之間的選用空格。例如,若要匹配空括號對,例如 ()
或 ( )
,請使用模式 '%(%s*%)
'。(模式 '%s*
' 匹配零個或多個空格。括號在模式中具有特殊含義,因此我們必須使用 `%
´ 跳脫它們。)另一個範例,模式 '[_%a][_%w]*
' 匹配 Lua 程式中的識別碼:一個以字母或底線開頭的序列,後跟零個或多個底線或字母數字字元。
與 `*
´ 相似,修飾符 `-
´ 也會比對原始類別中零個或多個字元。不過,它不是比對最長的序列,而是比對最短的序列。有時,`*
´ 或 `-
´ 之間沒有差異,但通常它們會呈現出截然不同的結果。例如,如果你嘗試使用樣式 '[_%a][_%w]-
' 尋找識別碼,你只會找到第一個字母,因為 '[_%w]-
' 永遠會比對空序列。另一方面,假設你想要在 C 程式中尋找註解。許多人會先嘗試 '/%*.*%*/
'(也就是一個 "/*"
後面接著一個任意字元序列,再後面接著一個 "*/"
,並寫入適當的跳脫字元)。然而,由於 '.*
' 會盡可能地擴充,程式中的第一個 "/*"
只會與最後一個 "*/"
關閉
test = "int x; /* x */ int y; /* y */" print(string.gsub(test, "/%*.*%*/", "<COMMENT>")) --> int x; <COMMENT>相反地,樣式 '
.-
' 會擴充最少必要的數量以找到第一個 "*/"
,這樣你才能得到想要的結果
test = "int x; /* x */ int y; /* y */" print(string.gsub(test, "/%*.-%*/", "<COMMENT>")) --> int x; <COMMENT> int y; <COMMENT>
最後一個修飾符 `?
´ 會比對一個可選字元。舉例來說,假設我們想要在文字中尋找一個整數,其中數字可能包含一個可選符號。樣式 '[+-]?%d+
' 可以完成這項工作,比對像 `"-12"`, `"23"`, 和 `"+1009"` 這樣的數字。`[+-]
` 是同時比對 `+
´ 或 `-
´ 符號的字元類別;後面的 `?
´ 使得符號成為可選的。
與其他一些系統不同,在 Lua 中,修飾符只能套用於字元類別;沒有辦法將樣式群組在修飾符之下。例如,沒有樣式可以比對一個可選字詞(除非該字詞只有一個字母)。通常你可以使用我們稍後會看到的進階技巧來規避這個限制。
如果一個樣式以 `^
´ 開頭,它只會比對主旨字串的開頭。類似地,如果它以 `$
´ 結尾,它只會比對主旨字串的結尾。這些標記可以用來限制你找到的樣式,也可以用來錨定樣式。例如,測試
if string.find(s, "^%d") then ...檢查字串 `s` 是否以數字開頭,而測試
if string.find(s, "^[+-]?%d+$") then ...檢查該字串是否表示一個整數,沒有其他前導或尾隨字元。
樣式中的另一個項目是 '%b
',它比對平衡字串。此項目寫作 '%bxy
',其中 x 和 y 是任何兩個不同的字元;x 作為開頭字元,y 作為結尾字元。例如,樣式 '%b()
' 比對字串中以 `(
´ 開頭並以對應的 `)
´ 結尾的部分
print(string.gsub("a (enclosed (in) parentheses) line", "%b()", "")) --> a line通常,這個樣式用作 '
%b()
'、'%b[]
'、'%b%{%}
' 或 '%b<>
',但你可以使用任何字元作為分隔符號。
版權所有 © 2003–2004 Roberto Ierusalimschy。保留所有權利。 | ![]() |