捕获

简介: 捕获

捕获机制允许根据一个模式从目标字符串中抽出与该模式匹配的内容用于后续用途,可以通过把模式中需要捕获的部分放到一对圆括号内来指定捕获。


对于具有捕获的模式,函数 string.match 会将所有捕获到的值作为单独的结果返回。换句话说,该函数会将字符串切分成多个被捕获的部分:

pair = "name = Anna"
key, value = string.match(pair, "(%a+)%s*=%s*(%a+)")
print(key, value)                                     --> name    Anna点击复制复制失败已复制


模式 "%a+" 表示一个非空的字母序列,模式 "%s*" 表示一个可能为空的空白序列。因此,上例中的这个模式表示一个字母序列,紧跟着空白序列、一个等号、空白序列以及另一个字母序列。模式中的两个字母序列分别被放在圆括号中,因此在匹配时就能捕获到他们。下面是一个类似的示例:

date = "Today is 2/3/2022"
d, m, y = string.match(date, "(%d+)/(%d+)/(%d+)")
print(d, m, y)    --> 2   3   2022


在这个示例中,使用了 3 个捕获,每个捕获对应一个数字序列。


在模式中,形如 "%n" 的分类(其中 n 是一个数字),表示匹配第 n 个捕获的副本。举一个典型的例子,假设想在一个字符串中寻找一个由单引号或双引号括起来的字符串。那么可能会尝试使用模式 "['"].-['"]" ,它表示一个引号后面跟任意内容及另外一个引号。但是,这种模式在处理像 "it's all right" 这样的字符串时会有问题。要解决这个问题,可以捕获第一个引号然后用它来指明第二个引号:

s = [[then he said: "it's all right"!]]
q, quotedPart = string.match(s, "([\"'])(.-)%1")
print(quotedPart)   --> it's all right
print(q)            --> "


1 个捕获是引号本身,第 2 个捕获是引号中内容(与 ".-" 匹配的子串)。


下面是一个类似的示例,用于匹配 Lua 语言中的长字符串的模式:

%[(=*)%[(.-)%]%1%]


它所匹配的内容依次是:一个左方括号、 0 个或多个等号、另一个左方括号、任意内容(即字符串的内容)、一个右方括号、相同数量的等号以及另一个右方括号:

p = "%[(=*)%[(.-)%]%1%]"
s = "a = [=[[[ something ]] ]==] ]=]; print(a)"
print(string.match(s, p))   --> =     [[ something ]] ]==]


第一个捕获是等号序列,第二个捕获是字符串内容。


被捕获对象的第三个用途是在函数 gsub 的代替字符串中。像模式一样,替代字符串同样可以包括像 "%n" 一样的字符分类,当发生替换时会被替换为相应的捕获。特别的, "%0" 意味着整个匹配,并且替换字符串中的百分号必须被转义为 "%%" 。下面这个示例会重复字符串中的每个字母,并且在每个被重复的字母之间插入一个减号:

print((string.gsub("hello lua!", "%a", "%0-%0")))   --> h-he-el-ll-lo-o l-lu-ua-a!点击复制复制失败已复制


下例交换了相邻的字符:

print((string.gsub("hello Lua", "(.)(.)", "%2%1")))   --> ehll ouLa点击复制复制失败已复制


以下是一个更有用的示例,让我们编写一个原始格式转换器,该格式转换器能读取 LATEX 风格的命令,并将他们转换成 XML 风格:

\command{some text}       -->       <command>some text</command>


如果不允许嵌套的命令,那么以下调用函数 string.gsub 的代码即可完成这项工作:

s = [[the \quote{task} is to \em{change} that.]]
s = string.gsub(s, "\\(%a+){(.-)}", "<%1>%2</%1>")
print(s)                                                --> the <quote>task</quote> is to <em>change</em> that.点击复制复制失败已复制


另外一个有用的示例是提出字符串两端的空格:

function trim(s)
  s = string.gsub(s, "^%s(.-)%s*$", "%1")
  return s
end


注意模式中修饰符的合理运用。两个定位标记( ^$ )保证了我们可以获取到整个字符串。由于中间的 ".-" 只会匹配尽可能少的内容,所以两个 "%s*" 便可匹配到首尾两端的空格。

目录
相关文章
|
8月前
|
C++
C++ 捕获所有异常并拿到错误原因的方法
C++ 捕获所有异常并拿到错误原因的方法
234 0
|
3月前
|
监控 Java
捕获线程执行异常的多种方法
【10月更文挑战第15天】捕获线程执行异常的方法多种多样,每种方法都有其特点和适用场景。在实际开发中,需要根据具体情况选择合适的方法或结合多种方法来实现全面有效的线程异常捕获。这有助于提高程序的健壮性和稳定性,减少因线程异常带来的潜在风险。
34 1
|
Java 程序员 API
异常(上)概述,捕捉异常,try-catch语句的详细使用
异常(上)概述,捕捉异常,try-catch语句的详细使用
233 0
|
8月前
|
Java
捕捉不到异常
捕捉不到异常
47 0
|
8月前
|
Java 数据库连接
Java异常捕获与处理
Java异常捕获与处理
43 0
|
数据采集 数据安全/隐私保护
如何使用异常处理机制捕获和处理请求失败的情况
在爬虫开发中,我们经常会遇到请求失败的情况,比如网络超时、连接错误、服务器拒绝等。这些情况会导致我们无法获取目标网页的内容,从而影响爬虫的效果和效率。为了解决这个问题,我们需要使用异常处理机制来捕获和处理请求失败的情况,从而提高爬虫的稳定性和稳定性。
133 0
如何使用异常处理机制捕获和处理请求失败的情况
|
索引 Python
Python基础 常见的异常类型 异常的捕获 异常的处理机制
python中常见的异常类型 1、ZeroDivisionError 除(或取模)零(所有数据类型) 2、IndexError #序列中没有此索引 3、KeyError #映射中没有这个键 4、NameError #未声明/初始化对象(没有属性) 5、SyntaxError #Python 语法错误 6、ValueError #传入无效的参数
Python基础 常见的异常类型 异常的捕获 异常的处理机制
有关异常的处理、捕获、抛出、自定义
有关异常的处理、捕获、抛出、自定义
114 0
对线程中未捕获的异常进行处理UncaughtExceptionHandler
对线程中未捕获的异常进行处理UncaughtExceptionHandler
Java异常被抛出或被捕获之后,代码是否继续执行的问题
在写程序的时候,我们经常被教导,要对异常的信息进行处理,哪里该抛出异常。但是,更多的时候,我们只是模仿异常的抛出,却不知道为什么要这样抛异常(被catch了?被向上抛了?后面的代码是否执行了?)。 接下来,我就简单的说一下异常抛出后的代码执行问题。
7295 1