正则表达式命令
LLDB 用户们好。我想开始定期发布博客文章,介绍 LLDB 的新功能和酷炫特性。今天我就从刚刚添加的一项功能开始:正则表达式命令。什么是正则表达式命令?它是一种智能别名,可以用来定义其他命令,使用“command regex” 命令定义。定义正则表达式命令时,需要提供命令名称,以及一系列正则表达式和替换对。正则表达式和替换对以标准的流编辑器搜索和替换格式提供:
s/<regex>/<subst>/
当后来输入命令时,它将剥离正则表达式命令名称和任何后续空格,并将原始参数字符串传递到您的正则表达式列表中,按照输入顺序进行匹配。第一个 <regex> 匹配原始参数字符串后,将允许用 在由 <subst>.
假设我们想使用
"f"
作为命令来按帧索引选择帧。按帧索引选择帧的命令是 "frame select <num>"
命令,您可能并不总是想完整地输入它。我们可以使用正则表达式命令来简化操作:
(lldb) command regex f 's/([0-9]+)/frame select %1/'
"command regex f"
告诉解释器创建一个名为 "f"
的新正则表达式命令,当在命令行上输入以 "f"
开头的命令时,它会将剩余的命令文本与正则表达式 "([0-9]+)"
进行匹配,如果匹配成功,则会将任何带括号的子表达式进行替换。这里我们将数字正则表达式 "[0-9]+"
括起来,这将保存第一个匹配的结果,并允许将匹配的字符串替换到匹配替换文本 "frame select %1"
中。当我们从 LLDB 命令行使用新的正则表达式命令时,它会向我们展示正则表达式替换后生成的命令:
(lldb) f 12
frame select 12
任何正则表达式命令 "f" 后的前导空格都将在匹配正则表达式之前被剥离,但可能存在尾随空格,因为我们正在处理紧随初始
"f"
命令名称之后的剩余原始命令字符串。正则表达式也只查找任何一个或多个数字的序列。当前的正则表达式实际上会匹配:
(lldb) f 11 22 33
frame select 11
由于这不是我们想要的,因此我们应该使正则表达式更完整,检查行首(
^
)和行尾($),并允许在数字之后出现零个或多个空格([[:space:]]*
)。我们更新后的更安全的正则表达式命令行如下所示:
(lldb) command regex f 's/^([0-9]+)[[:space:]]*$/frame select %1/'
现在我们可以像
"f 12 "
(注意尾随空格)那样输入命令,仍然可以获得正确的替换,而我们之前的示例 "f 11 22 33"
将不再匹配:
(lldb) f 11 22 33
error: Command contents '11 22 33' failed to match any regular expression in the 'f' regex command.
让我们更进一步,也使用
f
命令来模拟 GDB 的 finish
命令,当它在没有参数的情况下被输入时。我们还将修改此命令以监控单个“+”或“ - ”后面跟着一个数字,以表示使用 frame select 命令的 --relative 选项进行相对帧更改:
(lldb) frame select --relative
可以在命令行上输入多个正则表达式,或者在实时 LLDB 调试会话中输入时使用多行模式。以下是粗体文本中用户输入的内容:
(lldb) commands regex f
以 's///' 形式输入正则表达式,并用空行结束:
s/^([0-9]+)[[:space:]]*$/frame select %1/
s/^([+-][0-9]+)[[:space:]]*$/frame select --relative=%1/
s/^[[:space:]]*$/finish/
(lldb) f
finish
...
(lldb) f -1
frame select --relative=-1
...
(lldb) f +1
frame select --relative=+1
...
(lldb) f 12
frame select 12
希望您能看到使用这些命令自定义 LLDB 命令行体验的可能性。您可以将任何正则表达式命令添加到您的 ~/.lldbinit 文件中,以便在调试会话中始终定义您的正则表达式命令。