mirror of
https://github.com/nonebot/nonebot2.git
synced 2024-11-30 17:15:08 +08:00
✨ Feature: 添加正则匹配文本注入 (#1457)
Co-authored-by: Ju4tCode <42488585+yanyongyu@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
8176cd189c
commit
36d7b44741
@ -38,6 +38,8 @@ SHELL_ARGV: Literal["_argv"] = "_argv"
|
|||||||
|
|
||||||
REGEX_MATCHED: Literal["_matched"] = "_matched"
|
REGEX_MATCHED: Literal["_matched"] = "_matched"
|
||||||
"""正则匹配结果存储 key"""
|
"""正则匹配结果存储 key"""
|
||||||
|
REGEX_STR: Literal["_matched_str"] = "_matched_str"
|
||||||
|
"""正则匹配文本存储 key"""
|
||||||
REGEX_GROUP: Literal["_matched_groups"] = "_matched_groups"
|
REGEX_GROUP: Literal["_matched_groups"] = "_matched_groups"
|
||||||
"""正则匹配 group 元组存储 key"""
|
"""正则匹配 group 元组存储 key"""
|
||||||
REGEX_DICT: Literal["_matched_dict"] = "_matched_dict"
|
REGEX_DICT: Literal["_matched_dict"] = "_matched_dict"
|
||||||
|
@ -5,6 +5,7 @@ FrontMatter:
|
|||||||
description: nonebot.params 模块
|
description: nonebot.params 模块
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import warnings
|
||||||
from typing import Any, Dict, List, Tuple, Union, Optional
|
from typing import Any, Dict, List, Tuple, Union, Optional
|
||||||
|
|
||||||
from nonebot.typing import T_State
|
from nonebot.typing import T_State
|
||||||
@ -24,6 +25,7 @@ from nonebot.internal.params import MatcherParam as MatcherParam
|
|||||||
from nonebot.internal.params import ExceptionParam as ExceptionParam
|
from nonebot.internal.params import ExceptionParam as ExceptionParam
|
||||||
from nonebot.consts import (
|
from nonebot.consts import (
|
||||||
CMD_KEY,
|
CMD_KEY,
|
||||||
|
REGEX_STR,
|
||||||
PREFIX_KEY,
|
PREFIX_KEY,
|
||||||
REGEX_DICT,
|
REGEX_DICT,
|
||||||
SHELL_ARGS,
|
SHELL_ARGS,
|
||||||
@ -136,9 +138,24 @@ def _regex_matched(state: T_State) -> str:
|
|||||||
|
|
||||||
def RegexMatched() -> str:
|
def RegexMatched() -> str:
|
||||||
"""正则匹配结果"""
|
"""正则匹配结果"""
|
||||||
|
warnings.warn(
|
||||||
|
'"RegexMatched()" will be changed to "re.Match" object, '
|
||||||
|
'use "RegexStr()" instead. '
|
||||||
|
"See https://github.com/nonebot/nonebot2/pull/1453 .",
|
||||||
|
DeprecationWarning,
|
||||||
|
)
|
||||||
return Depends(_regex_matched, use_cache=False)
|
return Depends(_regex_matched, use_cache=False)
|
||||||
|
|
||||||
|
|
||||||
|
def _regex_str(state: T_State) -> str:
|
||||||
|
return state[REGEX_STR]
|
||||||
|
|
||||||
|
|
||||||
|
def RegexStr() -> str:
|
||||||
|
"""正则匹配结果文本"""
|
||||||
|
return Depends(_regex_str, use_cache=False)
|
||||||
|
|
||||||
|
|
||||||
def _regex_group(state: T_State):
|
def _regex_group(state: T_State):
|
||||||
return state[REGEX_GROUP]
|
return state[REGEX_GROUP]
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ from nonebot.params import Command, EventToMe, CommandArg
|
|||||||
from nonebot.adapters import Bot, Event, Message, MessageSegment
|
from nonebot.adapters import Bot, Event, Message, MessageSegment
|
||||||
from nonebot.consts import (
|
from nonebot.consts import (
|
||||||
CMD_KEY,
|
CMD_KEY,
|
||||||
|
REGEX_STR,
|
||||||
PREFIX_KEY,
|
PREFIX_KEY,
|
||||||
REGEX_DICT,
|
REGEX_DICT,
|
||||||
SHELL_ARGS,
|
SHELL_ARGS,
|
||||||
@ -616,6 +617,7 @@ class RegexRule:
|
|||||||
return False
|
return False
|
||||||
if matched := re.search(self.regex, str(msg), self.flags):
|
if matched := re.search(self.regex, str(msg), self.flags):
|
||||||
state[REGEX_MATCHED] = matched.group()
|
state[REGEX_MATCHED] = matched.group()
|
||||||
|
state[REGEX_STR] = matched.group()
|
||||||
state[REGEX_GROUP] = matched.groups()
|
state[REGEX_GROUP] = matched.groups()
|
||||||
state[REGEX_DICT] = matched.groupdict()
|
state[REGEX_DICT] = matched.groupdict()
|
||||||
return True
|
return True
|
||||||
@ -626,7 +628,7 @@ class RegexRule:
|
|||||||
def regex(regex: str, flags: Union[int, re.RegexFlag] = 0) -> Rule:
|
def regex(regex: str, flags: Union[int, re.RegexFlag] = 0) -> Rule:
|
||||||
"""匹配符合正则表达式的消息字符串。
|
"""匹配符合正则表达式的消息字符串。
|
||||||
|
|
||||||
可以通过 {ref}`nonebot.params.RegexMatched` 获取匹配成功的字符串,
|
可以通过 {ref}`nonebot.params.RegexStr` 获取匹配成功的字符串,
|
||||||
通过 {ref}`nonebot.params.RegexGroup` 获取匹配成功的 group 元组,
|
通过 {ref}`nonebot.params.RegexGroup` 获取匹配成功的 group 元组,
|
||||||
通过 {ref}`nonebot.params.RegexDict` 获取匹配成功的 group 字典。
|
通过 {ref}`nonebot.params.RegexDict` 获取匹配成功的 group 字典。
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ from nonebot.params import (
|
|||||||
Command,
|
Command,
|
||||||
Keyword,
|
Keyword,
|
||||||
Endswith,
|
Endswith,
|
||||||
|
RegexStr,
|
||||||
Fullmatch,
|
Fullmatch,
|
||||||
RegexDict,
|
RegexDict,
|
||||||
CommandArg,
|
CommandArg,
|
||||||
@ -71,6 +72,10 @@ async def regex_matched(regex_matched: str = RegexMatched()) -> str:
|
|||||||
return regex_matched
|
return regex_matched
|
||||||
|
|
||||||
|
|
||||||
|
async def regex_str(regex_matched: str = RegexStr()) -> str:
|
||||||
|
return regex_matched
|
||||||
|
|
||||||
|
|
||||||
async def startswith(startswith: str = Startswith()) -> str:
|
async def startswith(startswith: str = Startswith()) -> str:
|
||||||
return startswith
|
return startswith
|
||||||
|
|
||||||
|
@ -163,6 +163,7 @@ async def test_state(app: App, load_plugin):
|
|||||||
from nonebot.params import StateParam, DependParam
|
from nonebot.params import StateParam, DependParam
|
||||||
from nonebot.consts import (
|
from nonebot.consts import (
|
||||||
CMD_KEY,
|
CMD_KEY,
|
||||||
|
REGEX_STR,
|
||||||
PREFIX_KEY,
|
PREFIX_KEY,
|
||||||
REGEX_DICT,
|
REGEX_DICT,
|
||||||
SHELL_ARGS,
|
SHELL_ARGS,
|
||||||
@ -183,6 +184,7 @@ async def test_state(app: App, load_plugin):
|
|||||||
keyword,
|
keyword,
|
||||||
endswith,
|
endswith,
|
||||||
fullmatch,
|
fullmatch,
|
||||||
|
regex_str,
|
||||||
regex_dict,
|
regex_dict,
|
||||||
startswith,
|
startswith,
|
||||||
command_arg,
|
command_arg,
|
||||||
@ -207,6 +209,7 @@ async def test_state(app: App, load_plugin):
|
|||||||
SHELL_ARGV: ["-h"],
|
SHELL_ARGV: ["-h"],
|
||||||
SHELL_ARGS: {"help": True},
|
SHELL_ARGS: {"help": True},
|
||||||
REGEX_MATCHED: "[cq:test,arg=value]",
|
REGEX_MATCHED: "[cq:test,arg=value]",
|
||||||
|
REGEX_STR: "[cq:test,arg=value]",
|
||||||
REGEX_GROUP: ("test", "arg=value"),
|
REGEX_GROUP: ("test", "arg=value"),
|
||||||
REGEX_DICT: {"type": "test", "arg": "value"},
|
REGEX_DICT: {"type": "test", "arg": "value"},
|
||||||
STARTSWITH_KEY: "startswith",
|
STARTSWITH_KEY: "startswith",
|
||||||
@ -271,6 +274,12 @@ async def test_state(app: App, load_plugin):
|
|||||||
ctx.pass_params(state=fake_state)
|
ctx.pass_params(state=fake_state)
|
||||||
ctx.should_return(fake_state[REGEX_MATCHED])
|
ctx.should_return(fake_state[REGEX_MATCHED])
|
||||||
|
|
||||||
|
async with app.test_dependent(
|
||||||
|
regex_str, allow_types=[StateParam, DependParam]
|
||||||
|
) as ctx:
|
||||||
|
ctx.pass_params(state=fake_state)
|
||||||
|
ctx.should_return(fake_state[REGEX_STR])
|
||||||
|
|
||||||
async with app.test_dependent(
|
async with app.test_dependent(
|
||||||
regex_group, allow_types=[StateParam, DependParam]
|
regex_group, allow_types=[StateParam, DependParam]
|
||||||
) as ctx:
|
) as ctx:
|
||||||
|
@ -328,7 +328,7 @@ async def test_shell_command(app: App):
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"pattern,type,text,expected,matched,group,dict",
|
"pattern,type,text,expected,matched,string,group,dict",
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
r"(?P<key>key\d)",
|
r"(?P<key>key\d)",
|
||||||
@ -336,11 +336,12 @@ async def test_shell_command(app: App):
|
|||||||
"_key1_",
|
"_key1_",
|
||||||
True,
|
True,
|
||||||
"key1",
|
"key1",
|
||||||
|
"key1",
|
||||||
("key1",),
|
("key1",),
|
||||||
{"key": "key1"},
|
{"key": "key1"},
|
||||||
),
|
),
|
||||||
(r"foo", "message", None, False, None, None, None),
|
(r"foo", "message", None, False, None, None, None, None),
|
||||||
(r"foo", "notice", "foo", False, None, None, None),
|
(r"foo", "notice", "foo", False, None, None, None, None),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_regex(
|
async def test_regex(
|
||||||
@ -350,12 +351,13 @@ async def test_regex(
|
|||||||
text: Optional[str],
|
text: Optional[str],
|
||||||
expected: bool,
|
expected: bool,
|
||||||
matched: Optional[str],
|
matched: Optional[str],
|
||||||
|
string: Optional[str],
|
||||||
group: Optional[Tuple[str, ...]],
|
group: Optional[Tuple[str, ...]],
|
||||||
dict: Optional[Dict[str, str]],
|
dict: Optional[Dict[str, str]],
|
||||||
):
|
):
|
||||||
from nonebot.typing import T_State
|
from nonebot.typing import T_State
|
||||||
from nonebot.rule import RegexRule, regex
|
from nonebot.rule import RegexRule, regex
|
||||||
from nonebot.consts import REGEX_DICT, REGEX_GROUP, REGEX_MATCHED
|
from nonebot.consts import REGEX_STR, REGEX_DICT, REGEX_GROUP, REGEX_MATCHED
|
||||||
|
|
||||||
test_regex = regex(pattern)
|
test_regex = regex(pattern)
|
||||||
dependent = list(test_regex.checkers)[0]
|
dependent = list(test_regex.checkers)[0]
|
||||||
@ -369,6 +371,7 @@ async def test_regex(
|
|||||||
state = {}
|
state = {}
|
||||||
assert await dependent(event=event, state=state) == expected
|
assert await dependent(event=event, state=state) == expected
|
||||||
assert state.get(REGEX_MATCHED) == matched
|
assert state.get(REGEX_MATCHED) == matched
|
||||||
|
assert state.get(REGEX_STR) == string
|
||||||
assert state.get(REGEX_GROUP) == group
|
assert state.get(REGEX_GROUP) == group
|
||||||
assert state.get(REGEX_DICT) == dict
|
assert state.get(REGEX_DICT) == dict
|
||||||
|
|
||||||
|
@ -321,18 +321,18 @@ matcher = on_shell_command("cmd")
|
|||||||
async def _(foo: List[Union[str, MessageSegment]] = ShellCommandArgv()): ...
|
async def _(foo: List[Union[str, MessageSegment]] = ShellCommandArgv()): ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### RegexMatched
|
### RegexStr
|
||||||
|
|
||||||
获取正则匹配结果。
|
获取正则匹配结果的文本。
|
||||||
|
|
||||||
```python {7}
|
```python {7}
|
||||||
from nonebot import on_regex
|
from nonebot import on_regex
|
||||||
from nonebot.params import RegexMatched
|
from nonebot.params import RegexStr
|
||||||
|
|
||||||
matcher = on_regex("regex")
|
matcher = on_regex("regex")
|
||||||
|
|
||||||
@matcher.handle()
|
@matcher.handle()
|
||||||
async def _(foo: str = RegexMatched()): ...
|
async def _(foo: str = RegexStr()): ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### RegexGroup
|
### RegexGroup
|
||||||
|
Loading…
Reference in New Issue
Block a user