这个正则为什么无法限制字符个数?

思否 问答 已采纳 👍 3 含 AI 优化版

问题

这个正则为什么无法限制字符个数?

在 SegmentFault 查看原问题 →

由大模型辅助整理,保留原意,优化结构与可读性。

问题概述

正则 /^(.{1,50},?)+$/gm 本意是想限制每 50 个字符后必须有一个逗号分隔,但实际测试发现它并没有真正限制住总字符数,为什么?

涉及技术

正则表达式、量词与分组

期望结果

理解该正则失效的原因,并得到修正方案。

回答

原始回答

2021-10-22 /^(.{1,50},?)+$/gm 可以看成 /^(.{1,50},?)+$/ 可以看成 /^(.{1,50})+$/可以看成 /^(.{1,50})(.{1,50})$/ 这不就是无限个数字嘛?所以 , 不能省略。所以看上去应该 /^(.{1,50}(,|$))+/gm

AI 优化 · 回答整理

解答思路

问题出在逗号 ,?可选的(? 表示 0 次或 1 次),一旦逗号可以不出现,整个 (.{1,50},?) 分组就退化成了 (.{1,50}),而多个 (.{1,50}) 又可以被外层的 + 无限重复拼接,等价于对字符数完全没有限制。

详细说明

逐步简化理解这个正则:

  • /^(.{1,50},?)+$/gm
  • 因为 ,? 可以匹配 0 次,等价于 /^(.{1,50})+$/gm
  • (.{1,50})+ 可以展开成 (.{1,50})(.{1,50})(.{1,50})...,这本质上就是「任意数量个不超过 50 字符的片段拼在一起」,总长度没有上限。

修正方案:让逗号变成“必须存在,或者到达字符串末尾”,而不是“可选”:

/^(.{1,50}(,|$))+/gm
  • (,|$):每个片段后面必须紧跟一个逗号,或者到达行末($),这样就堵住了逗号被跳过、片段无限拼接的漏洞。

小结

? 表示可选而非必须,一旦分隔符是可选的,重复量词 + 就会让分组无限拼接,从而使字符数限制失效;把可选分隔符改成“分隔符或结尾”的必选条件即可修复。

由大模型辅助整理,保留原意,补充结构与代码格式。

回答转载自 SegmentFault

评论

评论功能即将开放。你也可以通过 邮件GitHub Issue 反馈。