一、Lua 中的模式匹配
与其他脚本不同,Lua 语言既没有使用 POSIX 正则表达式,也没有使用 Perl 正则表达式进行模式匹配。
主要是因为大小问题,因为一个典型的 POSIX 正则表达式实现需要 4000 多行,比 Lua 语言标准库总大小的一半还大,所以 Lua 语言模式匹配自行实现,代码只有 600 行。
二、模式匹配相关函数
Lua 的字符串标准库提供了基于模式的 4 个函数。分别是 string.find
、string.gsub
、string.match
、string.gmatch
值得一提,这里的下标都是从 1 开始,和 java、kotlin 有区别。
2-1、string.find(s, pattern, init, plain)
在指定的目标 s (字符串)中搜索指定的模式 pattern
参数:
- s:需要匹配的目标字符串
- pattern:匹配的模式,在简单的模式中,可以是需要匹配的一个字符串
- init:可选,是一个索引,用于说明从目标字符串的哪个位置开始索引
- plain:可选,是一个布尔值,用于说明是否进行简单搜索。所谓简单搜索就是忽略模式而在目标字符串中进行单纯的“查找子字符串”。在匹配一些特殊字符时,可以使用。
返回值:
如果匹配成功,则返回匹配到的模式开始位置的索引和结束位置的索引。
举几个例子
普通使用
一般通过 find
匹配到后,会返回开始和结束的下标,然后可以通过 sub
进行截取
s1 = "hello world"
local i, j = string.find(s1, "hello")
print(i, j) --> 1 5
print(string.sub(s1, i, j)) --> hello
print(string.sub(s1, s1:find("world"))) --> world
指定位置搜索
指定起始位置进行搜索,第三行代码中,因为从第二个开始搜索(即 “ello world”) “hello” ,所以搜索不到,则返回 nil
s1 = "hello world"
print(string.find(s1, "hello", 1)) --> 1 5
print(string.find(s1, "hello", 2)) --> nil
简单搜索
如果需要进行一些特殊字符的匹配,例如 [
、]
这些,则可以简单匹配。
如果取消简单模式,[world]
就是正则表达式了,意思为匹配这五个字母中的任意一个即可,a [world]
中最先出现的是 w
,即第四个字母。
s2 = "a [world]"
print(string.find(s2, "[world]", 1, true)) --> 3 9
print(string.find(s2, "[world]", 1, false)) --> 4 4
正则匹配
如果没有设置为简单搜索,则会进行正则匹配
date = "Today is 12/04/2022"
print(string.sub(date,string.find(date,"%d+/%d+/%d+"))) --> 12/04/2022
local s3 = ";$% **#$hello13"
-- %a+ 可以匹配 1-n 字母,会匹配到开头的空字符串
print(string.sub(s3, string.find(s3, "%a+", 3))) --> hello
值得注意,必须要传入第三个参数,才能传第四个参数
2-2、string.match(s, pattern, init)
与 string.find
一样,都用于在一个字符串中搜索模式。
区别在于两者的返回值,string.match
返回的是目标字符串中与模式相匹配的那部分子串,而非模式所在的位置。
参数:
- s: 需要匹配的目标字符串
- pattern: 匹配的模式
- init: 可选,说明从目标字符串的哪个位置开始搜索,默认值为 1
返回值:
如果匹配成功,则返回匹配成功的那部分子串
举个例子
s1 &#