1. 程式人生 > 其它 >lua模式匹配

lua模式匹配

新入門skynet系列視訊b站網址 https://www.bilibili.com/video/BV19d4y1678X

  • 普通字串
  • 模式字串

普通字串

在普通字串中, 字元 \ 是轉移字元。也就是說\有特殊意義。

-- \a 表示響鈴 
-- \n表示換行 
-- \"可以表示雙引號 
-- \\ 可以表示 \本身
--如果我們想在字串中單獨使用雙引號 就會報錯
print(" i'm ok,you'are right,單獨的一個引號 "不能使用 ") --這一行就會報錯
--改成這樣
print(" i'm ok,you'are right,單獨的一個引號 \"不能使用 ") 

模式字串

下面主要是討論模式匹配中的 作為模式使用的字串。

% 這個符號也是是轉義符 主要是用於模式字串,在普通字串中是沒有特殊意義的

模式字串本質是普通字串,只是lua提供的相關模式匹配函式可以很好的理解模式字串中 % 表示的意思。

^$()%.[]*+-? 都是魔法字元,有特殊的意義.如果想在模式字串中單純表示魔法字元,必須先轉移。比如我想顯示+,則 %+ `

. 表示任意字元

一般匹配

%a 是字母

%d 是數字

local str = "9_a5aa2bb_7"
local mod = "%d" --想匹配一個數字

for pat in string.gmatch(str, mod) do --把匹配出來的所有結果 一個個遍歷出來
    print(pat)
    
end

--結果
9
5
2
7

%d就是一個數字字符集。當我使用這個mod做匹配時,目的是希望匹配到這個字符集中的一個字元。當然一次只匹配一個字元。這個字符集裡面的所有字元是 0123456789

實際 [0-9]也可以表示這個字符集。改變 第2行

local str = "9_a5aa2bb_7"
local mod = "[0-9]" --想匹配一個數字

for pat in string.gmatch(str, mod) do --配出來的所有結果 一個個遍歷出來
    print(pat)
    
end

--結果
9
5
2
7

補集

local str = "9_h5ell2o_7"
local mod = "%D" --想匹配一個 非數字

for pat in string.gmatch(str, mod) do --把匹配出來的所有結果 一個個遍歷出來
    print(pat)
    
end

--結果
_
h
e
l
l
o
_

這裡補集就是把 %d 換成了 %D。但是如果我想要 冒號的補集合呢。看下面

local str = "he;llo;"
local mod = "[^;]" --想匹配一個 ;的補集

for pat in string.gmatch(str, mod) do --把匹配出來的所有結果 一個個遍歷出來
    print(pat)
    
end

--結果
h
e
l
l
o

實際上 數字的補集也可以用 [^0-9]

下面是更多例子

print( "我們開始討論lua的模式匹配")

-- ^$()%.[]*+-?  都是魔法字元,有特殊的意義.如果想在模式字串中單純表示魔法字元,必須先轉義。比如我想顯示+,則 %+ 

print("string.find      找到目標字串的起始位置和結束位置") --s 是源
s = "hello world"
begin = 5
print(string.find(s,"hello"))       --1       5 返回找到的字串的起始和結束位置 
print(string.find(s,"world"))       --7       11
print(string.find(s,"l"))           --3       3
print(string.find(s,"l",begin))     --10      10 begin表示從s字串的5個位置開始找

print("string.match     找到匹配目標的字串") --s 是源

s= "123bbcc456ff"
begin = 4
print(string.match(s,"123")) --123  返回與"123"匹配的字串
print(string.match(s,"%d+")) --123  返回與"%d+"匹配的字串 %d表示一個數字, + 表示一個或者一個以上數字, %d+ 即表示一個或者多個數字組成的字串
print(string.match(s,"%d+",begin))   --456 返回與"%d+"匹配的字串 注意從s的第四個位置開始找


print("string.gsub    用指定的字串替換目標字串,並返回替換後的樣子 和替換的次數") --s 是源

s = "hello world"
replace_count = 2 --表示替換次數
print(string.gsub(s,"world","agang"))--把world替換成agang,返回2個值,一個是hello agang 一個是 1 表示替換的次數 
print(string.gsub(s,"l","x"))                   --把l替換成x,返回 hexxo worxd     3
print(string.gsub(s,"l","x",replace_count))     --把l替換成x,返回 hexxo worxd    2

--下面測試 + 匹配 和 * 匹配 
s= [[
    function main() 
        local test = function()
            print(  )
        end
    end
 ]]
print("+ 表示匹配的個數滿足 >= 1 ") 
print(string.gsub(s,"%(%s+%)","<>")) --%s表示空格 ()因為都是魔法字元 所以為了表示本來的字元 就加了轉移字元%
print("* 表示匹配的個數滿足 >= 0 ") 
print(string.gsub(s,"%(%s*%)","<>"))

-- 下面測試 * 和 -
s =[[
    int age = 99; /*age是老虎的年齡*/ int id = 9527;/*id是老虎的編號*/
]]
print("正確的匹配註釋 ") 
print(string.gsub(s,"/%*.-%*/","//這是註釋資訊"))
print("錯誤的匹配註釋 導致把後面都當作註釋了") 
print(string.gsub(s,"/%*.*%*/","//這是註釋資訊"))





print("string.gmatch    找到匹配目標的字串,但是需要遍歷出來") --s 是源

s = "hello world ,安靜點"
print(string.gmatch(s,"%a+")) --string.gmatch 產生一個iter函式,每呼叫一次獲取一個結果匹配的結果 %a 表示一個字母 
for e in string.gmatch(s,"%a+") do
    print(e)
end

-- 下面測試 ?
s ="12 bb +34 hello -56"
print("找出帶符號的數字 這裡字元 ? 是表示可選的 ")
for e in string.gmatch(s,"[%+%-]?%d+") do --因為 + - 都是魔法字元,所在構建正負號集合時 +用%+ 表示 -用%-表示 
    print(e)
end

下面是捕獲的例子。一對括號 表示一個捕獲

--捕獲
s = [[
    cola said: "are you ready?" 
    david said: "i'am ok."
]]
--篩選出對話
print("篩選出對話 %1表示 在%1所在的位置使用第1個捕獲 這裡是捕獲雙引號  ")
--for e in string.gmatch(s,"([\"\'])(.*)%1") do --直接使用 雙引號 單引號 會導致模式字串混亂,所以在構建集合時用 \" 表示雙引號 \'表示單引號  
for e in string.gmatch(s,"([\"\'])(.-)%1") do --直接使用 雙引號 單引號 會導致模式字串混亂,所以在構建集合時用 \" 表示雙引號 \'表示單引號  
    print(e)
end

--把匹配的字串替換掉
s = "a12bc3def"
print("把每個整數取出來 ,假設取出的整數是x, 然後替換成x_x; %0表示匹配到的x")
print( string.gsub(s,"%d+"," %0_%0 ") )

--交換相鄰的數字
s="12 34 56"
print("把相鄰的兩個數字交換位置")
print( string.gsub(s,"(%d)(%d)"," %2%1 ") ) --%n 表示捕獲到的第n個字串 

--去掉字串的開頭和結束的空格
s="   12 34 56   "
print("去掉開始和結束的空格 之前:")
print(s)
print("之後:")
print( string.gsub(s,"^%s*(.*)%s*$","%1") )


--找到匹配的字串後,用匹配的字串作為key去獲取表中的value,然後用value替換
s =[[
    $name is $age years old
]]
local t = {name = "david",age = 60}
print( string.gsub(s,"%$(%a*)",t) ) --這裡因為 $是魔法字元 所以用%$進行轉義.不能直接使用 \$ 來表示 因為 print("\$") 無法編譯


--找到匹配的字串後,交給函式去處理,函式的返回值是value,然後用value替換
s =[[
    $name is $age years old
]]
local db = {name = "co",age = 70}
local function func(str)
    return db[str]
end
print( string.gsub(s,"%$(%a*)",func) ) --這裡因為 $是魔法字元 所以用%$進行轉義.不能直接使用 \$ 來表示 因為 print("\$") 無法編譯