diff --git a/nonebot/consts.py b/nonebot/consts.py index 17637149..e0e4bb6b 100644 --- a/nonebot/consts.py +++ b/nonebot/consts.py @@ -38,6 +38,8 @@ SHELL_ARGV: Literal["_argv"] = "_argv" REGEX_MATCHED: Literal["_matched"] = "_matched" """正则匹配结果存储 key""" +REGEX_STR: Literal["_matched_str"] = "_matched_str" +"""正则匹配文本存储 key""" REGEX_GROUP: Literal["_matched_groups"] = "_matched_groups" """正则匹配 group 元组存储 key""" REGEX_DICT: Literal["_matched_dict"] = "_matched_dict" diff --git a/nonebot/params.py b/nonebot/params.py index 4628aae9..27709d90 100644 --- a/nonebot/params.py +++ b/nonebot/params.py @@ -5,6 +5,7 @@ FrontMatter: description: nonebot.params 模块 """ +import warnings from typing import Any, Dict, List, Tuple, Union, Optional 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.consts import ( CMD_KEY, + REGEX_STR, PREFIX_KEY, REGEX_DICT, SHELL_ARGS, @@ -136,9 +138,24 @@ def _regex_matched(state: T_State) -> 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) +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): return state[REGEX_GROUP] diff --git a/nonebot/rule.py b/nonebot/rule.py index a7b4dd08..f49bb3c8 100644 --- a/nonebot/rule.py +++ b/nonebot/rule.py @@ -43,6 +43,7 @@ from nonebot.params import Command, EventToMe, CommandArg from nonebot.adapters import Bot, Event, Message, MessageSegment from nonebot.consts import ( CMD_KEY, + REGEX_STR, PREFIX_KEY, REGEX_DICT, SHELL_ARGS, @@ -616,6 +617,7 @@ class RegexRule: return False if matched := re.search(self.regex, str(msg), self.flags): state[REGEX_MATCHED] = matched.group() + state[REGEX_STR] = matched.group() state[REGEX_GROUP] = matched.groups() state[REGEX_DICT] = matched.groupdict() return True @@ -626,7 +628,7 @@ class RegexRule: 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.RegexDict` 获取匹配成功的 group 字典。 diff --git a/tests/plugins/param/param_state.py b/tests/plugins/param/param_state.py index 97f84bd4..1baed2b3 100644 --- a/tests/plugins/param/param_state.py +++ b/tests/plugins/param/param_state.py @@ -6,6 +6,7 @@ from nonebot.params import ( Command, Keyword, Endswith, + RegexStr, Fullmatch, RegexDict, CommandArg, @@ -71,6 +72,10 @@ async def regex_matched(regex_matched: str = RegexMatched()) -> str: return regex_matched +async def regex_str(regex_matched: str = RegexStr()) -> str: + return regex_matched + + async def startswith(startswith: str = Startswith()) -> str: return startswith diff --git a/tests/test_param.py b/tests/test_param.py index 05122371..f73f1307 100644 --- a/tests/test_param.py +++ b/tests/test_param.py @@ -163,6 +163,7 @@ async def test_state(app: App, load_plugin): from nonebot.params import StateParam, DependParam from nonebot.consts import ( CMD_KEY, + REGEX_STR, PREFIX_KEY, REGEX_DICT, SHELL_ARGS, @@ -183,6 +184,7 @@ async def test_state(app: App, load_plugin): keyword, endswith, fullmatch, + regex_str, regex_dict, startswith, command_arg, @@ -207,6 +209,7 @@ async def test_state(app: App, load_plugin): SHELL_ARGV: ["-h"], SHELL_ARGS: {"help": True}, REGEX_MATCHED: "[cq:test,arg=value]", + REGEX_STR: "[cq:test,arg=value]", REGEX_GROUP: ("test", "arg=value"), REGEX_DICT: {"type": "test", "arg": "value"}, STARTSWITH_KEY: "startswith", @@ -271,6 +274,12 @@ async def test_state(app: App, load_plugin): ctx.pass_params(state=fake_state) 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( regex_group, allow_types=[StateParam, DependParam] ) as ctx: diff --git a/tests/test_rule.py b/tests/test_rule.py index 1a7d4aab..04548477 100644 --- a/tests/test_rule.py +++ b/tests/test_rule.py @@ -328,7 +328,7 @@ async def test_shell_command(app: App): @pytest.mark.asyncio @pytest.mark.parametrize( - "pattern,type,text,expected,matched,group,dict", + "pattern,type,text,expected,matched,string,group,dict", [ ( r"(?Pkey\d)", @@ -336,11 +336,12 @@ async def test_shell_command(app: App): "_key1_", True, "key1", + "key1", ("key1",), {"key": "key1"}, ), - (r"foo", "message", None, False, None, None, None), - (r"foo", "notice", "foo", False, None, None, None), + (r"foo", "message", None, False, None, None, None, None), + (r"foo", "notice", "foo", False, None, None, None, None), ], ) async def test_regex( @@ -350,12 +351,13 @@ async def test_regex( text: Optional[str], expected: bool, matched: Optional[str], + string: Optional[str], group: Optional[Tuple[str, ...]], dict: Optional[Dict[str, str]], ): from nonebot.typing import T_State 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) dependent = list(test_regex.checkers)[0] @@ -369,6 +371,7 @@ async def test_regex( state = {} assert await dependent(event=event, state=state) == expected assert state.get(REGEX_MATCHED) == matched + assert state.get(REGEX_STR) == string assert state.get(REGEX_GROUP) == group assert state.get(REGEX_DICT) == dict diff --git a/website/docs/tutorial/plugin/create-handler.md b/website/docs/tutorial/plugin/create-handler.md index 382bfc0c..bffda282 100644 --- a/website/docs/tutorial/plugin/create-handler.md +++ b/website/docs/tutorial/plugin/create-handler.md @@ -321,18 +321,18 @@ matcher = on_shell_command("cmd") async def _(foo: List[Union[str, MessageSegment]] = ShellCommandArgv()): ... ``` -### RegexMatched +### RegexStr -获取正则匹配结果。 +获取正则匹配结果的文本。 ```python {7} from nonebot import on_regex -from nonebot.params import RegexMatched +from nonebot.params import RegexStr matcher = on_regex("regex") @matcher.handle() -async def _(foo: str = RegexMatched()): ... +async def _(foo: str = RegexStr()): ... ``` ### RegexGroup