mirror of
				https://github.com/nonebot/nonebot2.git
				synced 2025-11-03 16:36:44 +00:00 
			
		
		
		
	📝 Docs: 更新最佳实践部分的 Alconna 章节 (#2237)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
		
							
								
								
									
										372
									
								
								website/docs/best-practice/alconna/alconna.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										372
									
								
								website/docs/best-practice/alconna/alconna.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,372 @@
 | 
			
		||||
---
 | 
			
		||||
sidebar_position: 2
 | 
			
		||||
description: Alconna 基本介绍
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
# Alconna 命令解析
 | 
			
		||||
 | 
			
		||||
[Alconna](https://github.com/ArcletProject/Alconna) 作为命令解析器,
 | 
			
		||||
是一个简单、灵活、高效的命令参数解析器, 并且不局限于解析命令式字符串。
 | 
			
		||||
 | 
			
		||||
特点包括:
 | 
			
		||||
 | 
			
		||||
- 高效
 | 
			
		||||
- 直观的命令组件创建方式
 | 
			
		||||
- 强大的类型解析与类型转换功能
 | 
			
		||||
- 自定义的帮助信息格式
 | 
			
		||||
- 多语言支持
 | 
			
		||||
- 易用的快捷命令创建与使用
 | 
			
		||||
- 可创建命令补全会话, 以实现多轮连续的补全提示
 | 
			
		||||
- 可嵌套的多级子命令
 | 
			
		||||
- 正则匹配支持
 | 
			
		||||
 | 
			
		||||
## 命令编写
 | 
			
		||||
 | 
			
		||||
### 命令头
 | 
			
		||||
 | 
			
		||||
命令头是指命令的前缀 (Prefix) 与命令名 (Command) 的组合,例如 `!help` 中的 `!` 与 `help`。
 | 
			
		||||
 | 
			
		||||
在 Alconna 中,你可以传入多种类型的命令头,例如:
 | 
			
		||||
 | 
			
		||||
|             前缀             |   命令名   |                          匹配内容                           |       说明       |
 | 
			
		||||
| :--------------------------: | :--------: | :---------------------------------------------------------: | :--------------: |
 | 
			
		||||
|              -               |   "foo"    |                           `"foo"`                           | 无前缀的纯文字头 |
 | 
			
		||||
|              -               |    123     |                            `123`                            |  无前缀的元素头  |
 | 
			
		||||
|              -               | "re:\d{2}" |                           `"32"`                            |  无前缀的正则头  |
 | 
			
		||||
|              -               |    int     |                      `123` 或 `"456"`                       |  无前缀的类型头  |
 | 
			
		||||
|         [int, bool]          |     -      |                       `True` 或 `123`                       |  无名的元素类头  |
 | 
			
		||||
|        ["foo", "bar"]        |     -      |                     `"foo"` 或 `"bar"`                      |  无名的纯文字头  |
 | 
			
		||||
|        ["foo", "bar"]        |   "baz"    |                  `"foobaz"` 或 `"barbaz"`                   |     纯文字头     |
 | 
			
		||||
|         [int, bool]          |   "foo"    |             `[123, "foo"]` 或 `[False, "foo"]`              |      类型头      |
 | 
			
		||||
|         [123, 4567]          |   "foo"    |              `[123, "foo"]` 或 `[4567, "foo"]`              |      元素头      |
 | 
			
		||||
|      [nepattern.NUMBER]      |   "bar"    |            `[123, "bar"]` 或 `[123.456, "bar"]`             |     表达式头     |
 | 
			
		||||
|         [123, "foo"]         |   "bar"    |      `[123, "bar"]` 或 `"foobar"` 或 `["foo", "bar"]`       |      混合头      |
 | 
			
		||||
| [(int, "foo"), (456, "bar")] |   "baz"    | `[123, "foobaz"]` 或 `[456, "foobaz"]` 或 `[456, "barbaz"]` |       对头       |
 | 
			
		||||
 | 
			
		||||
其中
 | 
			
		||||
 | 
			
		||||
- 元素头:只会匹配对应的值,例如 `[123, 456]` 只会匹配 `123` 或 `456`,不会匹配 `789`。
 | 
			
		||||
- 纯文字头:只会匹配对应的字符串,例如 `["foo", "bar"]` 只会匹配 `"foo"` 或 `"bar"`,不会匹配 `"baz"`。
 | 
			
		||||
- 正则头:`re:xxx` 会将 `xxx` 转为正则表达式,然后匹配对应的字符串,例如 `re:\d{2}` 只会匹配 `"12"` 或 `"34"`,不会匹配 `"foo"`。
 | 
			
		||||
  **正则只在命令名上生效,命令前缀中的正则会被转义**。
 | 
			
		||||
- 类型头:只会匹配对应的类型,例如 `[int, bool]` 只会匹配 `123` 或 `True`,不会匹配 `"foo"`。
 | 
			
		||||
  - 无前缀的类型头:此时会将传入的值尝试转为 BasePattern,例如 `int` 会转为 `nepattern.INTEGER`。此时命令头会匹配对应的类型,
 | 
			
		||||
    例如 `int` 会匹配 `123` 或 `"456"`,但不会匹配 `"foo"`。同时,Alconna 会将命令头匹配到的值转为对应的类型,例如 `int` 会将 `"123"` 转为 `123`。
 | 
			
		||||
- 表达式头:只会匹配对应的表达式,例如 `[nepattern.NUMBER]` 只会匹配 `123` 或 `123.456`,不会匹配 `"foo"`。
 | 
			
		||||
- 混合头:
 | 
			
		||||
 | 
			
		||||
除了通过传入 `re:xxx` 来使用正则表达式外,Alconna 还提供了一种更加简洁的方式来使用正则表达式,那就是 Bracket Header。
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
from alconna import Alconna
 | 
			
		||||
 | 
			
		||||
alc = Alconna(".rd{roll:int}")
 | 
			
		||||
assert alc.parse(".rd123").header["roll"] == 123
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### 组件
 | 
			
		||||
 | 
			
		||||
我们可以看到主要的两大组件:`Option` 与 `Subcommand`。
 | 
			
		||||
 | 
			
		||||
`Option` 可以传入一组 `alias`,如 `Option("--foo|-F|--FOO|-f")` 或 `Option("--foo", alias=["-F"])`
 | 
			
		||||
 | 
			
		||||
传入别名后,Option 会选择其中长度最长的作为选项名称。若传入为 "--foo|-f",则命令名称为 "--foo"。
 | 
			
		||||
 | 
			
		||||
`Subcommand` 则可以传入自己的 **Option** 与 **Subcommand**。
 | 
			
		||||
 | 
			
		||||
他们拥有如下共同参数:
 | 
			
		||||
 | 
			
		||||
- `help_text`: 传入该组件的帮助信息
 | 
			
		||||
- `dest`: 被指定为解析完成时标注匹配结果的标识符,不传入时默认为选项或子命令的名称 (name)
 | 
			
		||||
- `requires`: 一段指定顺序的字符串列表,作为唯一的前置序列与命令嵌套替换
 | 
			
		||||
  对于命令 `test foo bar baz qux <a:int>` 来讲,因为`foo bar baz` 仅需要判断是否相等, 所以可以这么编写:
 | 
			
		||||
 | 
			
		||||
  ```python
 | 
			
		||||
  Alconna("test", Option("qux", Args.a[int], requires=["foo", "bar", "baz"]))
 | 
			
		||||
  ```
 | 
			
		||||
 | 
			
		||||
- `default`: 默认值,在该组件未被解析时使用使用该值替换。
 | 
			
		||||
 | 
			
		||||
  特别的,使用 `OptionResult` 或 `SubcomanndResult` 可以设置包括参数字典在内的默认值:
 | 
			
		||||
 | 
			
		||||
  ```python
 | 
			
		||||
  from arclet.alconna import Option, OptionResult
 | 
			
		||||
 | 
			
		||||
  opt1 = Option("--foo", default=False)
 | 
			
		||||
  opt2 = Option("--foo", default=OptionResult(value=False, args={"bar": 1}))
 | 
			
		||||
  ```
 | 
			
		||||
 | 
			
		||||
### 选项操作
 | 
			
		||||
 | 
			
		||||
`Option` 可以特别设置传入一类 `Action`,作为解析操作
 | 
			
		||||
 | 
			
		||||
`Action` 分为三类:
 | 
			
		||||
 | 
			
		||||
- `store`: 无 Args 时, 仅存储一个值, 默认为 Ellipsis; 有 Args 时, 后续的解析结果会覆盖之前的值
 | 
			
		||||
- `append`: 无 Args 时, 将多个值存为列表, 默认为 Ellipsis; 有 Args 时, 每个解析结果会追加到列表中
 | 
			
		||||
 | 
			
		||||
  当存在默认值并且不为列表时, 会自动将默认值变成列表, 以保证追加的正确性
 | 
			
		||||
 | 
			
		||||
- `count`: 无 Args 时, 计数器加一; 有 Args 时, 表现与 STORE 相同
 | 
			
		||||
 | 
			
		||||
  当存在默认值并且不为数字时, 会自动将默认值变成 1, 以保证计数器的正确性。
 | 
			
		||||
 | 
			
		||||
`Alconna` 提供了预制的几类 `action`:
 | 
			
		||||
 | 
			
		||||
- `store`,`store_value`,`store_true`,`store_false`
 | 
			
		||||
- `append`,`append_value`
 | 
			
		||||
- `count`
 | 
			
		||||
 | 
			
		||||
### 参数声明
 | 
			
		||||
 | 
			
		||||
`Args` 是用于声明命令参数的组件。
 | 
			
		||||
 | 
			
		||||
`Args` 是参数解析的基础组件,构造方法形如 `Args["foo", str]["bar", int]["baz", bool, False]`,
 | 
			
		||||
与函数签名类似,但是允许含有默认值的参数在前;同时支持 keyword-only 参数不依照构造顺序传入 (但是仍需要在非 keyword-only 参数之后)。
 | 
			
		||||
 | 
			
		||||
`Args` 中的 `name` 是用以标记解析出来的参数并存放于 **Arparma** 中,以方便用户调用。
 | 
			
		||||
 | 
			
		||||
其有三种为 Args 注解的标识符: `?`、`/` 与 `!`。标识符与 key 之间建议以 `;` 分隔:
 | 
			
		||||
 | 
			
		||||
- `!` 标识符表示该处传入的参数应不是规定的类型,或不在指定的值中。
 | 
			
		||||
- `?` 标识符表示该参数为可选参数,会在无参数匹配时跳过。
 | 
			
		||||
- `/` 标识符表示该参数的类型注解需要隐藏。
 | 
			
		||||
 | 
			
		||||
另外,对于参数的注释也可以标记在 `name` 中,其与 name 或者标识符 以 `#` 分割:
 | 
			
		||||
 | 
			
		||||
`foo#这是注释;?` 或 `foo?#这是注释`
 | 
			
		||||
 | 
			
		||||
:::tip
 | 
			
		||||
`Args` 中的 `name` 在实际命令中并不需要传入(keyword 参数除外):
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
from arclet.alconna import Alconna, Args
 | 
			
		||||
 | 
			
		||||
alc = Alconna("test", Args["foo", str])
 | 
			
		||||
alc.parse("test --foo abc")  # 错误
 | 
			
		||||
alc.parse("test abc")  # 之前
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
若需要 `test --foo abc`,你应该使用 `Option`:
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
from arclet.alconna import Alconna, Args, Option
 | 
			
		||||
 | 
			
		||||
alc = Alconna("test", Option("--foo", Args["foo", str]))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
`Args` 的参数类型表面上看需要传入一个 `type`,但实际上它需要的是一个 `nepattern.BasePattern` 的实例。
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
from arclet.alconna import Args
 | 
			
		||||
from nepattern import BasePattern
 | 
			
		||||
 | 
			
		||||
# 表示 foo 参数需要匹配一个 @number 样式的字符串
 | 
			
		||||
args = Args["foo", BasePattern("@\d+")]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
示例中传入的 `str` 是因为 `str` 已经注册在了 `nepattern.global_patterns` 中,因此会替换为 `nepattern.global_patterns[str]`。
 | 
			
		||||
 | 
			
		||||
默认支持的类型有:
 | 
			
		||||
 | 
			
		||||
- `str`: 匹配任意字符串
 | 
			
		||||
- `int`: 匹配整数
 | 
			
		||||
- `float`: 匹配浮点数
 | 
			
		||||
- `bool`: 匹配 `True` 与 `False` 以及他们小写形式
 | 
			
		||||
- `hex`: 匹配 `0x` 开头的十六进制字符串
 | 
			
		||||
- `url`: 匹配网址
 | 
			
		||||
- `email`: 匹配 `xxxx@xxx` 的字符串
 | 
			
		||||
- `ipv4`: 匹配 `xxx.xxx.xxx.xxx` 的字符串
 | 
			
		||||
- `list`: 匹配类似 `["foo","bar","baz"]` 的字符串
 | 
			
		||||
- `dict`: 匹配类似 `{"foo":"bar","baz":"qux"}` 的字符串
 | 
			
		||||
- `datetime`: 传入一个 `datetime` 支持的格式字符串,或时间戳
 | 
			
		||||
- `Any`: 匹配任意类型
 | 
			
		||||
- `AnyString`: 匹配任意类型,转为 `str`
 | 
			
		||||
- `Number`: 匹配 `int` 与 `float`,转为 `int`
 | 
			
		||||
 | 
			
		||||
同时可以使用 typing 中的类型:
 | 
			
		||||
 | 
			
		||||
- `Literal[X]`: 匹配其中的任意一个值
 | 
			
		||||
- `Union[X, Y]`: 匹配其中的任意一个类型
 | 
			
		||||
- `Optional[xxx]`: 会自动将默认值设为 `None`,并在解析失败时使用默认值
 | 
			
		||||
- `List[X]`: 匹配一个列表,其中的元素为 `X` 类型
 | 
			
		||||
- `Dict[X, Y]`: 匹配一个字典,其中的 key 为 `X` 类型,value 为 `Y` 类型
 | 
			
		||||
- ...
 | 
			
		||||
 | 
			
		||||
:::tip
 | 
			
		||||
几类特殊的传入标记:
 | 
			
		||||
 | 
			
		||||
- `"foo"`: 匹配字符串 "foo" (若没有某个 `BasePattern` 与之关联)
 | 
			
		||||
- `RawStr("foo")`: 匹配字符串 "foo" (不会被 `BasePattern` 替换)
 | 
			
		||||
- `"foo|bar|baz"`: 匹配 "foo" 或 "bar" 或 "baz"
 | 
			
		||||
- `[foo, bar, Baz, ...]`: 匹配其中的任意一个值或类型
 | 
			
		||||
- `Callable[[X], Y]`: 匹配一个参数为 `X` 类型的值,并返回通过该函数调用得到的 `Y` 类型的值
 | 
			
		||||
- `"re:xxx"`: 匹配一个正则表达式 `xxx`,会返回 Match[0]
 | 
			
		||||
- `"rep:xxx"`: 匹配一个正则表达式 `xxx`,会返回 `re.Match` 对象
 | 
			
		||||
- `{foo: bar, baz: qux}`: 匹配字典中的任意一个键, 并返回对应的值 (特殊的键 ... 会匹配任意的值)
 | 
			
		||||
- ...
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
`MultiVar` 则是一个特殊的标注,用于告知解析器该参数可以接受多个值,其构造方法形如 `MultiVar(str)`。
 | 
			
		||||
同样的还有 `KeyWordVar`,其构造方法形如 `KeyWordVar(str)`,用于告知解析器该参数为一个 keyword-only 参数。
 | 
			
		||||
 | 
			
		||||
:::tip
 | 
			
		||||
`MultiVar` 与 `KeyWordVar` 组合时,代表该参数为一个可接受多个 key-value 的参数,其构造方法形如 `MultiVar(KeyWordVar(str))`
 | 
			
		||||
 | 
			
		||||
`MultiVar` 与 `KeyWordVar` 也可以传入 `default` 参数,用于指定默认值。
 | 
			
		||||
 | 
			
		||||
`MultiVar` 不能在 `KeyWordVar` 之后传入。
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
### 紧凑命令
 | 
			
		||||
 | 
			
		||||
`Alconna`, `Option` 与 `Subcommand` 可以设置 `compact=True` 使得解析命令时允许名称与后随参数之间没有分隔:
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
from arclet.alconna import Alconna, Option, CommandMeta, Args
 | 
			
		||||
 | 
			
		||||
alc = Alconna("test", Args["foo", int], Option("BAR", Args["baz", str], compact=True), meta=CommandMeta(compact=True))
 | 
			
		||||
 | 
			
		||||
assert alc.parse("test123 BARabc").matched
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
这使得我们可以实现如下命令:
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
>>> from arclet.alconna import Alconna, Option, Args, append
 | 
			
		||||
>>> alc = Alconna("gcc", Option("--flag|-F", Args["content", str], action=append))
 | 
			
		||||
>>> alc.parse("gcc -Fabc -Fdef -Fxyz").query("flag.content")
 | 
			
		||||
['abc', 'def', 'xyz']
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
当 `Option` 的 `action` 为 `count` 时,其自动支持 `compact` 特性:
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
>>> from arclet.alconna import Alconna, Option, Args, count
 | 
			
		||||
>>> alc = Alconna("pp", Option("--verbose|-v", action=count, default=0))
 | 
			
		||||
>>> alc.parse("pp -vvv").query("verbose.value")
 | 
			
		||||
3
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## 命令特性
 | 
			
		||||
 | 
			
		||||
### 配置
 | 
			
		||||
 | 
			
		||||
`arclet.alconna.Namespace` 表示某一命名空间下的默认配置:
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
from arclet.alconna import config, namespace, Namespace
 | 
			
		||||
from arclet.alconna.tools import ShellTextFormatter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
np = Namespace("foo", prefixes=["/"])  # 创建 Namespace 对象,并进行初始配置
 | 
			
		||||
 | 
			
		||||
with namespace("bar") as np1:
 | 
			
		||||
    np1.prefixes = ["!"]    # 以上下文管理器方式配置命名空间,此时配置会自动注入上下文内创建的命令
 | 
			
		||||
    np1.formatter_type = ShellTextFormatter  # 设置此命名空间下的命令的 formatter 默认为 ShellTextFormatter
 | 
			
		||||
    np1.builtin_option_name["help"] = {"帮助", "-h"}  # 设置此命名空间下的命令的帮助选项名称
 | 
			
		||||
 | 
			
		||||
config.namespaces["foo"] = np  # 将命名空间挂载到 config 上
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
同时也提供了默认命名空间配置与修改方法:
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
from arclet.alconna import config, namespace, Namespace
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
config.default_namespace.prefixes = [...]  # 直接修改默认配置
 | 
			
		||||
 | 
			
		||||
np = Namespace("xxx", prefixes=[...])
 | 
			
		||||
config.default_namespace = np  # 更换默认的命名空间
 | 
			
		||||
 | 
			
		||||
with namespace(config.default_namespace.name) as np:
 | 
			
		||||
    np.prefixes = [...]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### 半自动补全
 | 
			
		||||
 | 
			
		||||
半自动补全为用户提供了推荐后续输入的功能。
 | 
			
		||||
 | 
			
		||||
补全默认通过 `--comp` 或 `-cp` 触发:(命名空间配置可修改名称)
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
from arclet.alconna import Alconna, Args, Option
 | 
			
		||||
 | 
			
		||||
alc = Alconna("test", Args["abc", int]) + Option("foo") + Option("bar")
 | 
			
		||||
alc.parse("test --comp")
 | 
			
		||||
 | 
			
		||||
'''
 | 
			
		||||
output
 | 
			
		||||
 | 
			
		||||
以下是建议的输入:
 | 
			
		||||
* <abc: int>
 | 
			
		||||
* --help
 | 
			
		||||
* -h
 | 
			
		||||
* -sct
 | 
			
		||||
* --shortcut
 | 
			
		||||
* foo
 | 
			
		||||
* bar
 | 
			
		||||
'''
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### 快捷指令
 | 
			
		||||
 | 
			
		||||
快捷指令顾名思义,可以为基础指令创建便捷的触发方式
 | 
			
		||||
 | 
			
		||||
一般情况下你可以通过 `Alconna.shortcut` 进行快捷指令操作 (创建,删除);
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
>>> from arclet.alconna import Alconna, Args
 | 
			
		||||
>>> alc = Alconna("setu", Args["count", int])
 | 
			
		||||
>>> alc.shortcut("涩图(\d+)张", {"args": ["{0}"]})
 | 
			
		||||
'Alconna::setu 的快截指令: "涩图(\\d+)张" 添加成功'
 | 
			
		||||
>>> alc.parse("涩图3张").query("count")
 | 
			
		||||
3
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
`shortcut` 的第一个参数为快捷指令名称,第二个参数为 `ShortcutArgs`,作为快捷指令的配置
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
class ShortcutArgs(TypedDict, Generic[TDC]):
 | 
			
		||||
    """快捷指令参数"""
 | 
			
		||||
 | 
			
		||||
    command: NotRequired[TDC]
 | 
			
		||||
    """快捷指令的命令"""
 | 
			
		||||
    args: NotRequired[list[Any]]
 | 
			
		||||
    """快捷指令的附带参数"""
 | 
			
		||||
    fuzzy: NotRequired[bool]
 | 
			
		||||
    """是否允许命令后随参数"""
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
当 `fuzzy` 为 False 时,传入 `"涩图1张 abc"` 之类的快捷指令将视为解析失败
 | 
			
		||||
 | 
			
		||||
快捷指令允许三类特殊的 placeholder:
 | 
			
		||||
 | 
			
		||||
- `{%X}`: 只用于 `command`, 如 `setu {%0}`,表示此处填入快截指令后随的第 X 个参数。
 | 
			
		||||
 | 
			
		||||
  例如,若快捷指令为 `涩图`, 配置为 `{"command": "setu {%0}"}`, 则指令 `涩图 1` 相当于 `setu 1`
 | 
			
		||||
 | 
			
		||||
- `{*}`: 只用于 `command`, 表示此处填入所有后随参数,并且可以通过 `{*X}` 的方式指定组合参数之间的分隔符。
 | 
			
		||||
- `{X}`: 用于 `command` 与 `args`, 表示此处填入可能的正则匹配的组:
 | 
			
		||||
  - 若 `command` 中存在匹配组 `(xxx)`,则 `{X}` 表示第 X 个匹配组的内容
 | 
			
		||||
  - 若 `command` 中存储匹配组 `(?P<xxx>...)`, 则 `{X}` 表示名字为 X 的匹配结果
 | 
			
		||||
 | 
			
		||||
除此之外, 通过内置选项 `--shortcut` 可以动态操作快捷指令。
 | 
			
		||||
 | 
			
		||||
### 使用模糊匹配
 | 
			
		||||
 | 
			
		||||
模糊匹配通过在 Alconna 中设置其 CommandMeta 开启。
 | 
			
		||||
 | 
			
		||||
模糊匹配会应用在任意需要进行名称判断的地方,如**命令名称**,**选项名称**和**参数名称**(如指定需要传入参数名称)。
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
from arclet.alconna import Alconna, CommandMeta
 | 
			
		||||
 | 
			
		||||
alc = Alconna("test_fuzzy", meta=CommandMeta(fuzzy_match=True))
 | 
			
		||||
alc.parse("test_fuzy")
 | 
			
		||||
# output: test_fuzy is not matched. Do you mean "test_fuzzy"?
 | 
			
		||||
```
 | 
			
		||||
		Reference in New Issue
	
	Block a user