网上找了一些关于gsub模式匹配资料,但是都不全面细致,所以打算翻译官方文档。以下内容翻译自《Lua 5.3 Reference Manual》6.4.1 - Patterns。
------ 我是一条分割线------
Lua中的模式匹配用正则表达式来描述,它被用于string.find
, string.gmatch
,string.gsub
, 和 string.match
.匹配一种模式。本结将讲述它的语法和模式字符串所代表的意思(及,它所匹配的字符串)。
--词汇解释
1. 字母,代表[a-zA-Z]
2. 字符,对所有符号的统称
3. 字母数字表,字母和数字的统称
4. 空白(空格)字符: 例如(‘ ’,'\t’)
字符集:
一个字符集用于代表一些字符的集合。下面的字符组合可以描述一个字符集:
1. X:(X不能是特殊字符 ^$()%.[]*+-?中的一个)代表X字母;
2. .:(一个点)代表所有的字符;
3. %a:代表所有的字母;
4. %c:代表所有的控制字符;(自己百度控制字符)
5. %d:代表所有数字;
6. %g:代表除了空格字符的所有可以打印的字符;
7. %l:代表所有的小写字符;
8. %p:代表所有的标点符号;
9. %s:代表所有的空白字符;
10.%u:代表所有的大写字母;
11.%w:代表所有字母表中的字符;
12.%x:代表所有的十六进制数字;
13.%x:(x不是字母数字表中的字符)代表x字符本身。通常用于转意显示特殊字符。任何非字母数字表中的特殊字符都可以用一个百分号后面跟这个字符来进行模式匹配。
14. [Set]:表示用Set中的所有字符代表的一个字符集合。字符区间可以用“-”,以升序的方式,分隔它的最后的几个字母来表示。上面讲述的用%x字符组合匹配代表的字符集合还可以用于其它字符集的元素。
比如,[%w_](或者)[_%w]代表所有的字母数字表中的字符和下划线组成的集合,[0-7]代表八进制,[0-7%l%-]代表八进制数字、小写字母以及‘-’字符组成的集合。
你可以在一个字符集中的开头位置放置一个].你也可以在一个字符集的开头或者结束放置一个连字符。(你也可以在两种情况中加入转意字符)
字符区间和字符集合有交叉的情况下,你写的模式匹配是错误的。因此,模式[%a-z]或者[a-%%]都是无效的模式。
15.[^Set]:代表上述模式所代表集合的补集。
用单个字母代表的集合(%a,%c,等),字母对应的大写字母代表集合的补集。例如,%S表示所有非空白字符。
字母,空格,和其他字符组合根据地域不同定义不同。举个实例,集合[a-z]也可能与%l代表的集合不一样。
模式匹配项
一个模式匹配项可以是:
1. 单个集合,它代表集合中的所有字符;
2. 一个集合后跟一个“*”,它代表集合中有0个或多个集合中的字符。匹配会尽可能的长的匹配方式进行。
3. 一个集合后跟一个“+”,它表示集合中的字符重复一次或者多次。匹配会尽可能的长的匹配方式进行。
4. 一个集合后跟一个“-”,它表示集合中的字符重复0次或者多次。和“*”不同,它代表的匹配火按最小的字符串匹配。
5. 一个字符后跟一个“?”,它代表字符在集合中出现了0次或一次。它会尽可能地按出现一次匹配。
6.%n,n是1-9的数字,这样的表达式与第n次匹配上的字符串相等(参见下面):
%bxy, x和y是两个不同的字符;这样的表达式与以x开头,y结尾,x和y达成一个平衡。这句话的意思是,如果从左边往右边读,x计数+1,y计数-1,结尾的y得到的和是等于0。例如,表达式%b()匹配的是左右匹配的圆括号。
举例:
local str = "abccc(ddd)dbc"
print(string.gsub(str,"%b()", "Hello"))
输出结果是 : abcccHellodbc 1
7.%f[Set], 边界匹配模式,它匹配一个在任何位置下一个字符属于[Set],上一个字符不属于[Set]的字符串。Set可以是之前描述的任何字符集合。字符串的开头和结尾都被当做是“\0”处理。
举例:
local str = "\0abccc (ddd)dbc"
print(string.gsub(str,"%f[a-zA-Z]", "###"))
输出是:###abccc (###ddd)###dbc 3
local str = "\0abccc (ddd)dbc "
print(string.gsub(str,"%f[a-zA-Z\0]", "###"))
输出是:abccc (###ddd)###dbc 2
模式:
一个模式是一系列子模式的组合。一个尖括号'^'在模式的开头代表匹配字符串的开头。一个‘$’放在模式的最后代表字符串末尾匹配。放在模式的其它位置‘^’和'$'代表字符本身。
8.Captures(捕获):
一个模式可以用一对圆括号将它的子模式括起来。它代表Captures(捕获)。当匹配成功后,原来字符串中满足Captures的所有子字符串将保留下来。Captures会根据它的左边括号编号。例如,模式"(a*(.)%w(%s*))",a*(.)%w(%s*)
匹配上的部分计数为第一次Capture(编号为1),与字符‘.’匹配的字符串编号为2,和“%s*”匹配的部分编号为3.
作为一种特例,空的捕获()捕获的是当前字符串的位置(一个数字)。例如,我们用"()aa()"去匹配字符串"flaaap",得到两个捕获:3和5.
例如:
local str = "abc AC ghl"
print(string.find(str, "(%a+)%s*[A-Z]+%s*(%a+)"))
==》1 10 abc ghl
local str = "abc AC ghl"
print(string.find(str, "((%a+)%s*[A-Z]+%s*(%a+))"))==》1 10 abc AC ghl abc ghl
----- 我是一条分割线-----
翻译过程中发现一些不好理解的地方,在这些地方我就加了额外的例子帮助理解。如果我翻译的不准确,理解上不对,欢迎大家留言区指正。