0
# Message Matching
1
2
Specialized handlers for matching and responding to specific message patterns and commands. These provide convenient ways to create handlers for common message matching scenarios.
3
4
## Capabilities
5
6
### Command Matching
7
8
Match messages that start with command prefixes and handle command arguments.
9
10
```python { .api }
11
def on_command(
12
cmd: Union[str, tuple[str, ...]],
13
rule: Optional[Rule] = None,
14
aliases: Optional[set[Union[str, tuple[str, ...]]]] = None,
15
force_whitespace: Optional[Union[str, bool]] = None,
16
permission: Optional[Permission] = None,
17
handlers: Optional[list[_Handler]] = None,
18
temp: bool = False,
19
expire_time: Optional[Union[datetime, timedelta]] = None,
20
priority: int = 1,
21
block: bool = False,
22
state: Optional[T_State] = None
23
) -> type[Matcher]:
24
"""
25
Create a command handler.
26
27
Parameters:
28
- cmd: Command name (str) or command tuple (for sub-commands)
29
- rule: Additional rule for matching
30
- aliases: Alternative command names
31
- force_whitespace: Force whitespace after command
32
- permission: Permission for handling command
33
- handlers: List of handler functions
34
- temp: Whether this is a temporary matcher
35
- expire_time: When temporary matcher expires
36
- priority: Handler priority (lower = higher priority)
37
- block: Whether to block further handler execution
38
- state: Initial state data
39
40
Returns:
41
type[Matcher]: Matcher class for command events
42
"""
43
```
44
45
Usage example:
46
47
```python
48
import nonebot
49
from nonebot import on_command
50
from nonebot.adapters import Bot, Event
51
from nonebot.params import CommandArg
52
53
# Simple command
54
hello = on_command("hello")
55
56
@hello.handle()
57
async def handle_hello(bot: Bot, event: Event, args=CommandArg()):
58
name = args.extract_plain_text().strip()
59
if name:
60
await bot.send(event, f"Hello, {name}!")
61
else:
62
await bot.send(event, "Hello, world!")
63
64
# Command with sub-commands
65
weather = on_command(("weather", "today"))
66
67
@weather.handle()
68
async def handle_weather_today(bot: Bot, event: Event):
69
await bot.send(event, "Today's weather: Sunny")
70
71
# Command with aliases
72
ping = on_command("ping", aliases={"test", "status"})
73
74
@ping.handle()
75
async def handle_ping(bot: Bot, event: Event):
76
await bot.send(event, "Pong!")
77
```
78
79
### Shell Command Matching
80
81
Match commands with shell-style argument parsing.
82
83
```python { .api }
84
def on_shell_command(
85
cmd: Union[str, tuple[str, ...]],
86
rule: Optional[Rule] = None,
87
aliases: Optional[set[Union[str, tuple[str, ...]]]] = None,
88
parser: Optional[ArgumentParser] = None,
89
permission: Optional[Permission] = None,
90
handlers: Optional[list[_Handler]] = None,
91
temp: bool = False,
92
expire_time: Optional[Union[datetime, timedelta]] = None,
93
priority: int = 1,
94
block: bool = False,
95
state: Optional[T_State] = None
96
) -> type[Matcher]:
97
"""
98
Create a shell command handler with argument parsing.
99
100
Parameters:
101
- cmd: Command name or tuple
102
- rule: Additional rule for matching
103
- aliases: Alternative command names
104
- parser: ArgumentParser for parsing arguments
105
- permission: Permission for handling command
106
- handlers: List of handler functions
107
- temp: Whether this is a temporary matcher
108
- expire_time: When temporary matcher expires
109
- priority: Handler priority (lower = higher priority)
110
- block: Whether to block further handler execution
111
- state: Initial state data
112
113
Returns:
114
type[Matcher]: Matcher class for shell command events
115
"""
116
```
117
118
Usage example:
119
120
```python
121
import nonebot
122
from nonebot import on_shell_command
123
from nonebot.adapters import Bot, Event
124
from nonebot.params import ShellCommandArgs
125
from nonebot.rule import ArgumentParser
126
127
# Create argument parser
128
parser = ArgumentParser()
129
parser.add_argument("--name", type=str, default="world")
130
parser.add_argument("--count", type=int, default=1)
131
132
# Create shell command
133
greet = on_shell_command("greet", parser=parser)
134
135
@greet.handle()
136
async def handle_greet(bot: Bot, event: Event, args=ShellCommandArgs()):
137
name = args.name
138
count = args.count
139
140
for i in range(count):
141
await bot.send(event, f"Hello, {name}!")
142
```
143
144
### Text Pattern Matching
145
146
Match messages that start with, end with, or exactly match specific text.
147
148
```python { .api }
149
def on_startswith(
150
msg: Union[str, tuple[str, ...]],
151
ignorecase: bool = False,
152
rule: Optional[Rule] = None,
153
permission: Optional[Permission] = None,
154
handlers: Optional[list[_Handler]] = None,
155
temp: bool = False,
156
expire_time: Optional[Union[datetime, timedelta]] = None,
157
priority: int = 1,
158
block: bool = False,
159
state: Optional[T_State] = None
160
) -> type[Matcher]:
161
"""
162
Create handler for messages starting with specific text.
163
164
Parameters:
165
- msg: Text or tuple of texts to match at start
166
- ignorecase: Whether to ignore case in matching
167
- rule: Additional rule for matching
168
- permission: Permission for handling messages
169
- handlers: List of handler functions
170
- temp: Whether this is a temporary matcher
171
- expire_time: When temporary matcher expires
172
- priority: Handler priority (lower = higher priority)
173
- block: Whether to block further handler execution
174
- state: Initial state data
175
176
Returns:
177
type[Matcher]: Matcher class for startswith events
178
"""
179
```
180
181
```python { .api }
182
def on_endswith(
183
msg: Union[str, tuple[str, ...]],
184
ignorecase: bool = False,
185
rule: Optional[Rule] = None,
186
permission: Optional[Permission] = None,
187
handlers: Optional[list[_Handler]] = None,
188
temp: bool = False,
189
expire_time: Optional[Union[datetime, timedelta]] = None,
190
priority: int = 1,
191
block: bool = False,
192
state: Optional[T_State] = None
193
) -> type[Matcher]:
194
"""
195
Create handler for messages ending with specific text.
196
197
Parameters:
198
- msg: Text or tuple of texts to match at end
199
- ignorecase: Whether to ignore case in matching
200
- rule: Additional rule for matching
201
- permission: Permission for handling messages
202
- handlers: List of handler functions
203
- temp: Whether this is a temporary matcher
204
- expire_time: When temporary matcher expires
205
- priority: Handler priority (lower = higher priority)
206
- block: Whether to block further handler execution
207
- state: Initial state data
208
209
Returns:
210
type[Matcher]: Matcher class for endswith events
211
"""
212
```
213
214
```python { .api }
215
def on_fullmatch(
216
msg: Union[str, tuple[str, ...]],
217
ignorecase: bool = False,
218
rule: Optional[Rule] = None,
219
permission: Optional[Permission] = None,
220
handlers: Optional[list[_Handler]] = None,
221
temp: bool = False,
222
expire_time: Optional[Union[datetime, timedelta]] = None,
223
priority: int = 1,
224
block: bool = False,
225
state: Optional[T_State] = None
226
) -> type[Matcher]:
227
"""
228
Create handler for messages that exactly match specific text.
229
230
Parameters:
231
- msg: Text or tuple of texts to match exactly
232
- ignorecase: Whether to ignore case in matching
233
- rule: Additional rule for matching
234
- permission: Permission for handling messages
235
- handlers: List of handler functions
236
- temp: Whether this is a temporary matcher
237
- expire_time: When temporary matcher expires
238
- priority: Handler priority (lower = higher priority)
239
- block: Whether to block further handler execution
240
- state: Initial state data
241
242
Returns:
243
type[Matcher]: Matcher class for fullmatch events
244
"""
245
```
246
247
Usage example:
248
249
```python
250
import nonebot
251
from nonebot import on_startswith, on_endswith, on_fullmatch
252
from nonebot.adapters import Bot, Event
253
from nonebot.params import Startswith, Endswith, Fullmatch
254
255
# Match messages starting with text
256
starts_handler = on_startswith("prefix")
257
258
@starts_handler.handle()
259
async def handle_starts(bot: Bot, event: Event, matched=Startswith()):
260
await bot.send(event, f"Matched prefix: {matched}")
261
262
# Match messages ending with text
263
ends_handler = on_endswith("suffix")
264
265
@ends_handler.handle()
266
async def handle_ends(bot: Bot, event: Event, matched=Endswith()):
267
await bot.send(event, f"Matched suffix: {matched}")
268
269
# Match exact text
270
exact_handler = on_fullmatch("exact")
271
272
@exact_handler.handle()
273
async def handle_exact(bot: Bot, event: Event, matched=Fullmatch()):
274
await bot.send(event, f"Exact match: {matched}")
275
```
276
277
### Keyword Matching
278
279
Match messages containing specific keywords.
280
281
```python { .api }
282
def on_keyword(
283
*keywords: str,
284
rule: Optional[Rule] = None,
285
permission: Optional[Permission] = None,
286
handlers: Optional[list[_Handler]] = None,
287
temp: bool = False,
288
expire_time: Optional[Union[datetime, timedelta]] = None,
289
priority: int = 1,
290
block: bool = False,
291
state: Optional[T_State] = None
292
) -> type[Matcher]:
293
"""
294
Create handler for messages containing keywords.
295
296
Parameters:
297
- *keywords: Keywords to search for in messages
298
- rule: Additional rule for matching
299
- permission: Permission for handling messages
300
- handlers: List of handler functions
301
- temp: Whether this is a temporary matcher
302
- expire_time: When temporary matcher expires
303
- priority: Handler priority (lower = higher priority)
304
- block: Whether to block further handler execution
305
- state: Initial state data
306
307
Returns:
308
type[Matcher]: Matcher class for keyword events
309
"""
310
```
311
312
Usage example:
313
314
```python
315
import nonebot
316
from nonebot import on_keyword
317
from nonebot.adapters import Bot, Event
318
from nonebot.params import Keyword
319
320
# Match messages with keywords
321
keyword_handler = on_keyword("help", "assist", "support")
322
323
@keyword_handler.handle()
324
async def handle_keyword(bot: Bot, event: Event, matched=Keyword()):
325
await bot.send(event, f"Detected keyword: {matched}")
326
await bot.send(event, "How can I help you?")
327
```
328
329
### Regular Expression Matching
330
331
Match messages using regular expressions for complex patterns.
332
333
```python { .api }
334
def on_regex(
335
pattern: Union[str, re.Pattern[str]],
336
flags: Union[int, re.RegexFlag] = 0,
337
rule: Optional[Rule] = None,
338
permission: Optional[Permission] = None,
339
handlers: Optional[list[_Handler]] = None,
340
temp: bool = False,
341
expire_time: Optional[Union[datetime, timedelta]] = None,
342
priority: int = 1,
343
block: bool = False,
344
state: Optional[T_State] = None
345
) -> type[Matcher]:
346
"""
347
Create handler for messages matching regular expressions.
348
349
Parameters:
350
- pattern: Regular expression pattern (str or compiled Pattern)
351
- flags: Regular expression flags
352
- rule: Additional rule for matching
353
- permission: Permission for handling messages
354
- handlers: List of handler functions
355
- temp: Whether this is a temporary matcher
356
- expire_time: When temporary matcher expires
357
- priority: Handler priority (lower = higher priority)
358
- block: Whether to block further handler execution
359
- state: Initial state data
360
361
Returns:
362
type[Matcher]: Matcher class for regex events
363
"""
364
```
365
366
Usage example:
367
368
```python
369
import nonebot
370
import re
371
from nonebot import on_regex
372
from nonebot.adapters import Bot, Event
373
from nonebot.params import RegexMatched, RegexStr, RegexGroup
374
375
# Match email addresses
376
email_pattern = r"([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})"
377
email_handler = on_regex(email_pattern)
378
379
@email_handler.handle()
380
async def handle_email(
381
bot: Bot,
382
event: Event,
383
matched=RegexMatched(),
384
email=RegexStr(0),
385
username=RegexStr(1),
386
domain=RegexStr(2)
387
):
388
await bot.send(event, f"Found email: {email}")
389
await bot.send(event, f"Username: {username}, Domain: {domain}")
390
391
# Match numbers with case-insensitive flag
392
number_handler = on_regex(r"number\s+(\d+)", flags=re.IGNORECASE)
393
394
@number_handler.handle()
395
async def handle_number(bot: Bot, event: Event, groups=RegexGroup()):
396
number = groups[0]
397
await bot.send(event, f"Number detected: {number}")
398
```
399
400
## Types
401
402
### Command Types
403
404
```python { .api }
405
class CommandGroup:
406
"""Group related commands together."""
407
408
def command(self, cmd: Union[str, tuple[str, ...]], **kwargs) -> type[Matcher]:
409
"""Create command in this group."""
410
411
class MatcherGroup:
412
"""Group related matchers together."""
413
414
def on(self, **kwargs) -> type[Matcher]:
415
"""Create matcher in this group."""
416
```
417
418
### Argument Parser
419
420
```python { .api }
421
class ArgumentParser:
422
"""Extended argument parser for shell commands."""
423
424
def add_argument(self, *args, **kwargs) -> None:
425
"""Add command line argument."""
426
427
class Namespace:
428
"""Argument namespace containing parsed arguments."""
429
```