1. 程式人生 > >Lua中正則表示式的使用整理

Lua中正則表示式的使用整理

在Lua中使用正則表示式進行模式匹配的string庫函式有這四個:

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

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

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

string.gmatch(str, pattern)

在Lua中進行模式匹配的時候支援的字元類如下:

Lua正則表示式
元字元 描述 備註
%a 匹配字母,無論大小寫
%b 匹配對稱字元,一般寫法為"%bxy",x為開始匹配字元,y為結束匹配字元,xy可隨意指定 例如:"%b<>"為匹配包括<>在內的所有字元
%c 匹配控制字元 例如:換行符\n、製表符\t等
%d 匹配數字0-9
%l 匹配小寫字母a-z
%p 匹配標點符號
%s 匹配空白符號
%u 匹配大寫字母A-Z
%w 匹配字母和數字
%x 匹配十六進位制數字
%z 匹配代表0的字元
以上字元類除了%b以外的大寫形式表示取反,也就是取小寫形式匹配集合的補集 例如:"%A"為匹配除字母外的其他字元,"%D"為匹配除數字外的其他字元
. 匹配任意字元
% 特殊字元的轉義字元 例如:"%."為匹配點號,"%%"為匹配百分比符號,跟"\""用來轉義引號類似
() 匹配與返回括號內的內容
[] 自定義匹配字符集 例如:"[a-z0-9,%]"匹配a-z、0-9、逗號以及百分比號
+ 匹配前一字元1次或多次
* 匹配前一字元0次或多次 最長匹配
- 匹配前一字元0次或多次 最短匹配
? 匹配前一字元0次或1次
^ 匹配字串開頭 例如:"^%d+"為以數字開頭的匹配
$ 匹配字串結尾 例如:"%d+$"為以數字結尾的匹配

普通元字元的例子:

-- %a
local str = "ab12"
print(string.gsub(str, "%a", "C"))  -- CC12 2
print(string.gsub(str, "%A", "C"))  -- abCC 2

-- %b
str = "12a<nice>bc"
print(string.match(str, "%b<>"))  -- <nice>

-- %c
str = "s12\naaa\tbb"
print(string.gsub(str, "%c", "Y"))  -- s12YaaaYbb   2
print(string.gsub(str, "%C", "Y"))
-- YYY
-- YYY YY  8

-- %d
str = "ab1c2d"
print(string.gsub(str, "%d", "6"))  -- ab6c6d   2
print(string.gsub(str, "%D", "6"))  -- 661626   4

-- %l
str = "AbA12Bc3"
print(string.gsub(str, "%l", "G"))  -- AGA12BG3 2
print(string.gsub(str, "%L", "G"))  -- GbGGGGcG 6

-- %p
str = "hello world!"
print(string.match(str, "%p"))  -- !
print(string.match(str, "%P"))  -- h

-- %s
str = "hello world!"
print(string.gsub(str, "%s", ","))  -- hello,world! 1
print(string.gsub(str, "%S", ","))  -- ,,,,, ,,,,,, 11

-- %u
str = "AbA12Bc3"
print(string.gsub(str, "%u", "U"))  -- UbU12Uc3 3
print(string.gsub(str, "%U", "U"))  -- AUAUUBUU 5

-- %w
str = "中文很6a"
print(string.gsub(str, "%w", "厲害"))  -- 中文很厲害厲害 2
print(string.gsub(str, "%W", "厲害"))  -- 厲害厲害厲害厲害厲害厲害厲害厲害厲害6a    9

-- %x
str = "MN1GeF"
print(string.gsub(str, "%x", "o"))  -- MNoGoo   3
print(string.gsub(str, "%X", "o"))  -- oo1oeF   3

-- %z
str = "0123489\0a"
print(string.gsub(str, "%z", "零"))  -- 0123489零a    1
print(string.gsub(str, "%Z", "零"))  -- 零零零零零零零  8

特殊元字元的例子:

-- .
local str = "a1&"
print(string.gsub(str, ".", "x"))  -- xxx   3

-- %
str = "%ab*%%"
print(string.gsub(str, "%%", "x"))  -- xab*xx   3
print(string.gsub(str, "%*", "y"))  -- %aby%%   1

-- ()
str = "<body>主幹</body>"
print(string.match(str, "<body>.+</body>"))  -- <body>主幹</body>
print(string.match(str, "<body>(.+)</body>"))  -- 主幹

-- []
str = "ab3cc8dmf,xx"
print(string.gsub(str, "[a5-8m-n,]", "z"))  -- zb3cczdzfzxx 4
print(string.gsub(str, "[^a5-8m-n,]", "z"))  -- azzzz8zmz,zz    8
--[[
    說明:
    "[^...]"會匹配不在...中的集合,即...的補集,例如"[^%d]"為匹配非數字字元,和"[%D]"效果一樣
    而"^..."匹配的是以...開頭,例如"^%d+"為以數字開頭的匹配
]]

-- ^
print(string.match("1abc", "^%d"))  -- 1
print(string.match("a1bc", "^%d"))  -- nil

-- $
print(string.match("abc1", "%d$"))  -- 1
print(string.match("ab1c", "%d$"))  -- nil

-- +
str = "ab12345ed"
print(string.match(str, "%d+"))  -- 12345

-- * -
str = "<a><b><c>"
print(string.gsub(str, "<.*>", "{ok}"))  -- {ok}    1
print(string.gsub(str, "<.->", "{ok}"))  -- {ok}{ok}{ok}    3
--[[
    說明:
    *和-比較類似,只是*進行最長匹配,而-是進行最短匹配
    所以在例子中使用*進行匹配的時候,會匹配第一個"<"到最後一個">"之間的所有內容進行替換,只匹配到了一次
    而使用-進行匹配的時候,則會第一個"<"到第一個">"之間的內容進行替換,一共匹配到了3次
]]

-- ?
print(string.match("abc100", "[+-]?%d+"))  -- 100
print(string.match("abc-100", "[+-]?%d+"))  -- -100
print(string.match("abc+100", "[+-]?%d+"))  -- +100
--[[
    說明:
    ?是匹配前一字元0次或1次
    在例子中即匹配字元類"[+-]"0次或1次,將這個匹配模式稍微改動一下,改成"^[+-]?%d+$"就可以檢查這個字串是否是整數了
]]

簡單的應用:

-- 判斷字串是否為純數字字串
function judgeNumString(str)
    return string.match(str, "%d+") == str
end

local str1 = "3497439"
local str2 = "83048a389b"

print(judgeNumString(str1), judgeNumString(str2))  -- true  false

-- 判斷是否是手機號碼(大陸)
function judgePhoneNum(str)
    return string.match(str,"[1][3-9]%d%d%d%d%d%d%d%d%d") == str
end

str1 = "13347823759"
str2 = "10348932849"

print(judgePhoneNum(str1), judgePhoneNum(str2))  -- true    false

參考: