第一版是为 Lua 5.0 编写的。虽然在很大程度上仍然适用于后续版本,但有一些区别。
第四版针对 Lua 5.3,可在 亚马逊 和其他书店购买。
购买本书,您还可以帮助 支持 Lua 项目。
用 Lua 编程 | ||
第三部分。标准库 第 20 章。字符串库 |
您可以使用字符类让模式更有用。字符类是模式中可以匹配特定集合中任何字符的项。例如,类 %d
匹配任何数字。因此,您可以使用模式 '%d%d/%d%d/%d%d%d%d
' 搜索格式为 dd/mm/yyyy
的日期。
s = "Deadline is 30/05/1999, firm" date = "%d%d/%d%d/%d%d%d%d" print(string.sub(s, string.find(s, date))) --> 30/05/1999下表列出了所有字符类
. | 所有字符 |
%a | 字母 |
%c | 控制字符 |
%d | 数字 |
%l | 小写字母 |
%p | 标点符号 |
%s | 空格字符 |
%u | 大写字母 |
%w | 字母数字字符 |
%x | 十六进制数字 |
%z | 表示为 0 的字符 |
任何这些类的上版本表示该类的补集。例如,'%A
' 表示所有非字母字符
print(string.gsub("hello, up-down!", "%A", ".")) --> hello..up.down. 4(
4
不是结果字符串的一部分。它是 gsub
的第二个结果,即替换的总数。打印 gsub
结果的其他示例将省略此计数。)
某些字符(称为魔术字符)在模式中使用时具有特殊含义。魔术字符是
( ) . % + - * ? [ ^ $字符 `
%
´ 用作这些魔术字符的转义符。因此,'%.
' 匹配一个点;'%%
' 匹配字符 `%
´ 本身。您不仅可以使用转义符 `%
´ 来转义魔术字符,还可以转义所有其他非字母数字字符。如有疑问,请谨慎行事并添加转义符。
对于 Lua,模式是正则字符串。它们没有特殊处理,并遵循与其他字符串相同的规则。只有在函数内部,它们才被解释为模式,并且只有那时 `%
´ 才起转义作用。因此,如果您需要在模式中添加引号,则必须使用与在其他字符串中添加引号相同的方法;例如,您可以使用 `\
´ 转义引号,它是 Lua 的转义字符。
字符集允许您创建自己的字符类,在方括号内组合不同的类和单个字符。例如,字符集“[%w_]
”匹配字母数字字符和下划线,字符集“[01]
”匹配二进制数字,字符集“[%[%]]
”匹配方括号。要计算文本中的元音数量,您可以编写
_, nvow = string.gsub(text, "[AEIOUaeiou]", "")您还可以在字符集中包含字符范围,方法是通过连字符分隔范围的第一个和最后一个字符来编写。您很少需要此功能,因为大多数有用的范围已经预定义;例如,“
[0-9]
”写成“%d
”更简单,“[0-9a-fA-F]
”与“%x
”相同。但是,如果您需要查找八进制数字,则可能更喜欢“[0-7]
”,而不是显式枚举(“[01234567]
”)。您可以通过以“^
´开头来获得字符集的补集:“[^0-7]
”查找任何不是八进制数字的字符,“[^\n]
”匹配任何与换行符不同的字符。但请记住,您可以使用其大写版本来否定简单的类:“%S
”比“[^%s]
”更简单。
字符类遵循为 Lua 设置的当前区域设置。因此,类“[a-z]
”可能不同于“%l
”。在适当的区域设置中,后一种形式包括字母,例如“ç
´和“ã
´”。除非您有充分的理由这样做,否则您应该始终使用后一种形式:它更简单、更便携、效率也略高。
您可以使用重复和可选部分的修饰符使模式更有用。Lua 中的模式提供四种修饰符
+ | 1 次或多次重复 |
* | 0 次或多次重复 |
- | 也 0 次或多次重复 |
? | 可选(0 次或 1 次出现) |
修饰符“+
´匹配原始类的一个或多个字符。它将始终获取与模式匹配的最长序列。例如,模式“%a+
”表示一个或多个字母,或一个单词
print(string.gsub("one, and two; and three", "%a+", "word")) --> word, word word; word word模式“
%d+
”匹配一个或多个数字(一个整数)
i, j = string.find("the number 1298 is even", "%d+") print(i,j) --> 12 15
修饰符“*
´类似于“+
´,但它也接受类字符的零次出现。一个典型的用法是匹配模式部分之间的可选空格。例如,要匹配一对空括号,例如 ()
或 ( )
,请使用模式“%(%s*%)
”。(模式“%s*
”匹配零个或多个空格。括号在模式中具有特殊含义,因此我们必须使用“%
´对其进行转义。)另一个示例,模式“[_%a][_%w]*
”匹配 Lua 程序中的标识符:以字母或下划线开头的序列,后跟零个或多个下划线或字母数字字符。
与 `*
´ 类似,修饰符 `-
´ 也匹配原始类中的零个或多个字符出现。然而,它不是匹配最长的序列,而是匹配最短的序列。有时,`*
´ 或 `-
´ 之间没有区别,但通常它们呈现出截然不同的结果。例如,如果你尝试使用模式 '[_%a][_%w]-
' 查找标识符,你将只找到第一个字母,因为 '[_%w]-
' 将始终匹配空序列。另一方面,假设你想要在 C 程序中查找注释。许多人会首先尝试 '/%*.*%*/
'(即一个 "/*"
后跟一个任意字符序列,后跟 "*/"
,用适当的转义符编写)。然而,由于 '.*
' 会尽可能地展开,程序中的第一个 "/*"
将仅与最后一个 "*/"
闭合
test = "int x; /* x */ int y; /* y */" print(string.gsub(test, "/%*.*%*/", "<COMMENT>")) --> int x; <COMMENT>相反,模式 '
.-
' 将展开查找第一个 "*/"
所需的最小量,以便你获得所需的结果
test = "int x; /* x */ int y; /* y */" print(string.gsub(test, "/%*.-%*/", "<COMMENT>")) --> int x; <COMMENT> int y; <COMMENT>
最后一个修饰符 `?
´ 匹配一个可选字符。例如,假设我们想要在文本中查找一个整数,其中该数字可能包含一个可选符号。模式 '[+-]?%d+
' 可以完成这项工作,匹配诸如 "-12"
、"23"
和 "+1009"
的数字。'[+-]
' 是一个字符类,它匹配 `+
´ 或 `-
´ 符号;后面的 `?
´ 使该符号成为可选的。
与其他一些系统不同,在 Lua 中修饰符只能应用于字符类;没有办法将模式分组在修饰符下。例如,没有模式可以匹配一个可选单词(除非该单词只有一个字母)。通常,你可以使用我们稍后将看到的某些高级技术来规避此限制。
如果一个模式以 `^
´ 开头,它将仅匹配目标字符串的开头。类似地,如果它以 `$
´ 结尾,它将仅匹配目标字符串的结尾。这些标记既可用于限制你找到的模式,也可用于锚定模式。例如,测试
if string.find(s, "^%d") then ...检查字符串
s
是否以数字开头,而测试
if string.find(s, "^[+-]?%d+$") then ...检查该字符串是否表示一个整数,没有其他前导或尾随字符。
模式中的另一个项目是“%b
”,它匹配平衡字符串。此项目写为“%bxy
”,其中x和y是任意两个不同的字符;x充当开始字符,y充当结束字符。例如,模式“%b()
”匹配以“(
´开头并在相应的“)
´结束的字符串部分
print(string.gsub("a (enclosed (in) parentheses) line", "%b()", "")) --> a line通常,此模式用作“
%b()
”、“%b[]
”、“%b%{%}
”或“%b<>
”,但您可以使用任何字符作为分隔符。
版权所有 © 2003–2004 Roberto Ierusalimschy。保留所有权利。 |