You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写与关键词顺序无关的正则表达式提取/send命令参数

问题:匹配/send命令中任意顺序的参数分组

需求是对/send命令后的参数进行分组,关键词包括at、after、until(对应时间参数)和for(对应时长参数),同时提取第一个数字作为postNumber,且参数顺序不固定。具体输入输出示例如下:

  • 输入:/send 1 at 11:00pm for 3min → 期望结果:postNumber = 1, sendAt = 11:00pm, duration = 3min
  • 输入:/send 1 for 3min → 期望结果:postNumber = 1, duration = 3min
  • 输入:/send 1 at 11:00pm → 期望结果:postNumber = 1, sendAt = 11:00pm
  • 输入:/send 1 until 11:00pm → 期望结果:postNumber = 1, until = 11:00pm
  • 输入:/send 1 for 3min at 11:00 pm → 期望结果:postNumber = 1, sendAt = 11:00 pm, duration = 3min
  • 输入:/send 1 at 11am for 1 h → 期望结果:postNumber = 1, sendAt = 11am, duration = 1 h

之前尝试的正则无法支持参数顺序无关的匹配:

(?<postNumber>\d+)(?: at (?<sendAt>.*))?(?: for (?<duration>.*))?(?: until (?<until>.*))?

使用正向预查的版本也存在问题,导致第一个组匹配异常:

(?<postNumber>\d+)(?=(?: at (?<timeToSend>.*)))?(?=(?: for (?<duration>.*)))?(?=(?: until (?<until>.*)))?

解决方案

要实现任意顺序的参数匹配,核心是独立匹配每个参数组,不依赖顺序,同时确保每个关键词对应的内容不会包含其他关键词(避免贪婪匹配导致的错误)。

直接生成对应命名组的正则

以下正则适配PCRE/JavaScript等支持命名捕获组的引擎,可直接捕获到postNumber、sendAt、after、until、duration这些目标分组:

^\/send (?<postNumber>\d+)(?:\s+(?:at\s+(?<sendAt>(?:(?!\s+(?:at|after|until|for)\b).*))|after\s+(?<after>(?:(?!\s+(?:at|after|until|for)\b).*))|until\s+(?<until>(?:(?!\s+(?:at|after|until|for)\b).*))|for\s+(?<duration>(?:(?!\s+(?:at|after|until|for)\b).*)))*$

正则逻辑解释

  • ^\/send :精准匹配命令开头的/send 前缀
  • (?<postNumber>\d+):捕获第一个连续数字作为postNumber
  • (?:\s+(?:...|...))*:匹配任意数量的参数组(顺序不限),每组前需有空格分隔
    • 针对at/after/until:用(?!\s+(?:at|after|until|for)\b)负向预查限制捕获内容,确保时间参数不会包含其他关键词,避免贪婪匹配吞掉后续参数
    • 针对for:同样用负向预查限制时长参数的范围,确保不会覆盖其他参数

原正则失效原因

  • 第一版正则是按固定顺序匹配的,后续分组必须在前面分组之后才能被捕获,无法处理参数顺序调换的场景
  • 正向预查版本中,预查不消耗字符,且.*贪婪匹配会吞掉所有后续内容,导致捕获逻辑完全失效

内容的提问来源于stack exchange,提问作者user13345587

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 11:02:47