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("\$") 无法编译

posted @ 2022-12-08 15:23  程序员阿钢  阅读(309)  评论(1编辑  收藏  举报