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