lua正則匹配中文 Lua的字串匹配與正規表示式

2021-10-12 14:35:48 字數 4173 閱讀 1415

lua的字串匹配與正規表示式

使用lua一段時間了,簡單總結下string庫中的幾個與正則相關的函式。這些函式是find,match, gmatch和gsub。然後是lua中支援的正則。文中的例子在lua5.3的命令列中試驗過。5.1版的需要在提示符前加乙個=號或加return空格。

string.find(s, pattern[, init[, plain]])

在字串s中匹配pattern,如果匹配成功返回第乙個匹配到的子串的起始索引和結束索引,如果pattern中有分組,分組匹配的內容也會接著兩個索引值之後返回。如果匹配失敗返回nil。

可選數值引數init表示從s中的哪個索引位置開始匹配,預設值是1,可以為負索引。

可選布林值引數plain為true時,pattern作為普通字串匹配,所有正則中的元字元都只被作為普通字元解析。(這個引數並不是匹配字串的結束索引)

string.find('hanazawa kana', 'na')

string.find('hanazawa kana', '[%a]+')

string.find('2015-5-12 13:53', '(%d+)-(%d+)-(%d+)')

string.find('2015-5-12 13:53', '(%d+)-(%d+)-(%d+)', 1, true)

nilstring.find('%a1234567890%a', '%a', 3, true)

string.match(s, pattern[, init])

在字串s中匹配pattern,如果匹配失敗返回nil。否則,當pattern中沒有分組時,返回第乙個匹配到的子串;當pattern中有分組時,返回第乙個匹配到子串的分組,多個分組就返回多個。可選引數init表示匹配字串的起始索引,預設為1,可以為負索引。

> string.match('2015-5-12 13:53', '%d+-%d+-%d+')

2015-5-12

> string.match('2015-5-12 13:53', '(%d+)-(%d+)-(%d+)')

> string.match('2015-5-12 13:53', '((%d+)-(%d+)-(%d+))')

2015-5-122015512

可以發現,所有用到match的地方都可以用find來實現。match是find的乙個簡化版

string.gmatch(s, pattern)

返回乙個迭代器。每當迭代器呼叫時,返回下乙個匹配到的子串,如果pattern中有分組,返回的是子串對應的分組。gmatch也可以用find和迴圈來實現。

> for s in string.gmatch('2015-5-12 22:20', '%d+') do print(s) end

> for s in string.gmatch('hanazawa kana', 'a(%a)a') do print(s) end --找出形如「a字母a」中間的字母nw

n> for k, v in string.gmatch('a=214,b=233', '(%w+)=(%w+)') do print(k, v) end

a214

b233

看上面第二個測試例子,處於兩個a字母中間的單個字母還有『z』,但迴圈並沒有輸出。原因是在'ana'匹配成功之後,接下來匹配是從'z'開始的,z沒有被匹配到。正確的模式pattern應該不要捕獲'a(%a)a'的後面的a,用python的正則可以寫成'a(\w)(?=a)',他不會消耗掉後面的a。但是lua不支援(?=...)。(python中\w表示單詞字元[a-za-z0-9_],記不清就把這類元字元列出來 如 %a寫成[a-za-z] 。)

string.gsub(s, pattern, repl[, n])

替換字串函式!這個功能應該是字串處理中實用性最強的乙個。

把字串中用模式pattern匹配到的所有子串替換為repl指代的子串,返回替換後的字串和替換的次數。可選數值引數n表示最多可替換的次數。

引數repl可以是正規表示式,也可以是函式。當repl是函式時,函式的引數是模式pattern捕獲的子串,和match類似,有分組返回分組,無分組返回整個子串。函式最後應該返回乙個字串。如果repl是正規表示式,可以用分組序號引用匹配到的分組。

> string.gsub('hanazawa kana', 'na', 'nya')

hanyazawa kanya

> string.gsub('hanazawa kana', 'na', function(s) return string.sub(s,1,1)..'y'..string.sub(s,2,2) end)

hanyazawa kanya

> string.gsub('hanazawa kana', '(n)(a)', function(a,b) return a..'y'..b end)

hanyazawa kanya

> string.gsub('hanazawa kana', '(n)(a)', '%1y%2')

hanyazawa kanya

lua中的正規表示式

正規表示式由元字元按照規則(語法)組成。lua中的特殊字元是%.^$+-*?,一共12個。它們和一般字元按規則構成了lua的正規表示式。

元字元描述表示式例項完整匹配的字串

字元普通字元除去%.()^$*+-?的字元,匹配字元本身kanakana

.匹配任意字元ka.akana

%轉義字元,改變後乙個字元的原有意思。當後面的接的是特殊字元時,將還原特殊字元的原意。%和一些特定的字母組合構成了lua的預定義字符集。%和數字1~9組合表示之前捕獲的分組k%wna

%%na%%

(a)n%1kana

%na%

ana[...]字符集(字元類)。匹配乙個包含於集合內的字元。[...]中的特殊字元將還原其原意,但有下面幾種特殊情況

1. %],%-,%^作為整體表示字元']','-','^'

2. 預定義字符集作為乙個整體表示對應字符集

3. 當]位於序列的第乙個字元時只表示字元']'

4. 形如[^...],[...-...]有特定的其他含義[a%]na

[%a]na

[%%a]na

]na[%]]na

[a-]na%na

wnawna

]na]na

-na[...-...]-表示ascii碼在它前乙個字元到它後乙個字元之間的所有字元[a-z]ana

[^...]不在...中的字元集合。[^0-9]na

[^^0-9]nakna

kna重複(數量詞)

*表示前乙個字元出現0次或多次[0-9]*

[a-z]*9*2009

na+表示前乙個字元出現1次或1次以上n+[0-9]+n2009

?表示前乙個字元出現0次或1次n?[0-9]+2009

預定義字符集

%s空白符[ \r\n\t\v\f]an[%s]?9an 9

%p標點符號an[%p]9an.9

%c控制字元

%w字母數字[a-za-z0-9][%w]+kana9

%a字母[a-za-z][%a]*kana

%l小寫字母[a-z]-

%u大寫字母[a-z]-

%d數字[0-9]-

%x16進製制數[0-9a-fa-f]-

%zascii碼是0的字元-

分組(...)表示式中用小括號包圍的子字串為乙個分組,分組從左到右(以左括號的位置),組序號從1開始遞增。ab(%d+)

(%d+)%1ab233

邊界匹配(屬於零寬斷言)

^匹配字串開頭^(%a)%w*abc123

$匹配字串結尾%w*(%d)$abc123

%b%bxy平衡匹配(匹配xy對)。這裡的x,y可以是任何字元,即使是特殊字元也是原來的含義,匹配到的子串以x開始,以y結束,並且如果從x開始,每遇到x,計算+1,遇到y計數-1,則結束的y是第乙個y使得計數等於0。就是匹配成對的符號,常見的如%b()匹配成對的括號%b()

%d+%b()(3+4(x*2))

2(3+4(x*2))

**備註**

1. lua不支援分組後面接重複詞(+*?),對於複雜的匹配可以用find+迴圈手動處理。

2. %bxy跟預定義字符集有區別,前者在[...]仍保持原意,後者則失去特殊意義

3. 上表中是lua對正則的支援,其他的正則如命名組,重複等並不能在lua中用。注意轉義字元是%不是\

參考

Lua模式匹配

模式匹配函式 在string庫中功能最強大的函式是 string.find 字串查詢 string.gsub 全域性字串替換 string.gfind 全域性字串查詢 string.gmatch 返回查詢到字串的迭代器 這些函式都是基於模式匹配的。與其他指令碼語言不同的是,lua並不使用posix規...

Lua模式匹配

模式匹配函式 在string庫中功能最強大的函式是 string.find 字串查詢 string.gsub 全域性字串替換 string.gfind 全域性字串查詢 string.gmatch 返回查詢到字串的迭代器 這些函式都是基於模式匹配的。與其他指令碼語言不同的是,lua並不使用posix規...

Lua模式匹配

模式匹配函式 在string庫中功能最強大的函式是 string.find 字串查詢 string.gsub 全域性字串替換 string.gfind 全域性字串查詢 string.gmatch 返回查詢到字串的迭代器 這些函式都是基於模式匹配的。與其他指令碼語言不同的是,lua並不使用posix規...