提问人:Robert S 提问时间:6/28/2021 更新时间:6/28/2021 访问量:171
JavaScript - 捕获重复组
JavaScript - Capture repeated group
问:
使用 JavaScript(或 VBScript) 是否可以从 %n:32+5000 中单独捕获以下组?
- 捕获组 1:%n
- 捕获组 2::32
- 捕获组 3:+5000
我尝试通过这个论坛搜索有关捕获重复组的信息,但给出的示例要么是使用不同的语言,如 .NET,要么提问者没有具体询问如何做我需要的事情。
到目前为止,我所做的最好的尝试是打开全局。此外,我正在使用 https://regex101.com/r/qBylQX/1 来帮助我可视化正在发生的事情;但是,到目前为止,我还没有破解它。(%n)(([:\+]\d+){0,2})
笔记:
- 每个 %n 只允许一个实例
- 每场比赛只允许 :\d+ 出现一次
- 每场比赛只允许出现一次 +\d+。
- 该模式可以出现在字符串中的任何位置。
答:
1赞
Ryszard Czech
6/28/2021
#1
用
(%n)(?:(:\d+)(\+\d+)?)?
请参阅正则表达式证明。
解释
--------------------------------------------------------------------------------
( group and capture to \1:
--------------------------------------------------------------------------------
%n '%n'
--------------------------------------------------------------------------------
) end of \1
--------------------------------------------------------------------------------
(?: group, but do not capture (optional
(matching the most amount possible)):
--------------------------------------------------------------------------------
( group and capture to \2:
--------------------------------------------------------------------------------
: ':'
--------------------------------------------------------------------------------
\d+ digits (0-9) (1 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
) end of \2
--------------------------------------------------------------------------------
( group and capture to \3 (optional
(matching the most amount possible)):
--------------------------------------------------------------------------------
\+ '+'
--------------------------------------------------------------------------------
\d+ digits (0-9) (1 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
)? end of \3 (NOTE: because you are using a
quantifier on this capture, only the
LAST repetition of the captured pattern
will be stored in \3)
--------------------------------------------------------------------------------
)? end of grouping
0赞
The fourth bird
6/28/2021
#2
使用此模式还可以匹配 2 次或 2 次,因为 和 都在字符类中。(%n)(([:\+]\d+){0,2})
:\d+
+\d+
:
+
重复捕获组 like 将仅捕获组中最后一次迭代的值。([:\+]\d+){0,2}
由于此重复位于外部捕获组 2 内,因此组 2 值将包含整个匹配项,并且您所追求的组中没有很好的值分离。
根据注释,其中任何一个只能出现一次,可以在比赛中出现。
如果要匹配 and 的两个组合,但如果它们不能相同,则可以使用带有反向引用的捕获组。:
+
这些值位于组 1、3 和 4 中。
(%n)(?:([:+])(\d+)(?:(?!\2)([:+]\d+))?)?(?!\S)
模式匹配:
(%n)
捕获组 1,匹配%n
(?:
非捕获组作为一个整体进行匹配([:+])
捕获组 2,匹配或:
+
(\d+)
捕获组 3,匹配 1+ 位数字(?:
非捕获组作为一个整体进行匹配(?!\2)
否定前瞻,断言右边的值与第 2 组中捕获的值不同([:+]\d+)
捕获组 4、匹配或:
+
)?
关闭组并使其成为可选
)?
关闭组并使其成为可选(?!\S)
在右侧断言空格边界以防止部分匹配
const regex = /(%n)(?:([:+])(\d+)(?:(?!\2)([:+]\d+))?)?(?!\S)/;
[
"%n:32+5000",
"%n:32",
"%n+5000",
"%n",
"%n+32:5000",
"%n+32",
"%n:5000",
"%n:32:5000",
"%n+32+5000"
].forEach(s => console.log(`${regex.test(s)} ==> ${s}`));
评论