核心在于清洗脏输入再识别,需清除隐形字符、统一中英文标点、删除来源信息、合并空白,再用上下文锚定正则匹配,最后必须经服务端校验。

不能靠粘贴后直接正则匹配就搞定,核心问题不在正则写得够不够全,而在用户输入源太脏——邀请码常混在富文本、带空格/换行/隐形字符的截图文字里,必须先清洗再识别。
粘贴文本时为什么onInput拿不到干净邀请码
用户从微信、短信或淘宝App复制“邀请码:ABC123XYZ”,实际粘贴进<input>的是含零宽空格(\u200B)、软连字符(\u00AD)、中文冒号(\uFF1A)甚至“来自 微信”尾巴的富文本。event.detail.value看着像纯文本,实则藏雷。
- 第一时间用
.replace(/[\u200B-\u200D\uFEFF\u00AD]/g, '')清除所有隐形控制符 - 把中文标点统一转英文:
.replace(/[\uFF1A\uFF08\uFF09\uFF0C\u3001]/g, m => ({':': ':', '(': '(', ')': ')', ',': ',', '、': ','}[m])) - 删掉来源信息:
.replace(/来自\s*[^\s]+/, '') - 合并换行和连续空白:
.replace(/[\r\n\s\u3000]+/g, ' ').trim()
正则怎么写才不漏掉常见邀请码格式
淘宝系邀请码没有统一长度或前缀,有纯数字(8823456)、字母+数字(TB7X9K2)、带分隔符(ABC-123-XYZ),甚至大小写混用(AbC7xYz)。别只写/[A-Za-z0-9]{6,12}/,它会把“订单号:123456789”里的123456789也当邀请码抓出来。
- 优先匹配带上下文的模式,比如
/(邀请码|邀约码|推荐码|ID)[::\s]*([A-Za-z0-9-]{6,12})/i,捕获第二组 - 若无上下文,限定边界:
/(?,避免嵌入长字符串中 - 支持短横分隔:
/[A-Za-z0-9]{2,5}-[A-Za-z0-9]{2,5}-[A-Za-z0-9]{2,5}/ - 全部加
i标志,忽略大小写
识别到疑似码后必须验证,否则全是假阳性
正则匹配只是筛出“长得像”的字符串,但ABC123XYZ可能是无效码、过期码、或别人家的码。用户点提交前,必须走一次轻量校验接口,否则体验崩坏。
- 别自己算校验位——淘宝/京东邀请码校验逻辑不公开,自实现等于白干
- 调用你后端提供的
/api/invite/verify?code=ABC123XYZ,返回{ valid: true, type: 'new_user' }才算数 - 前端加防抖:用户连续粘贴/修改,只发最后一次请求,用
setTimeout+clearTimeout控制 - 验证失败时,别只弹
邀请码错误,提示更具体:已过期 / 不属于当前活动 / 该码已被使用
真正难的不是写出能匹配的正则,而是让邀请码从微信聊天记录、截图OCR结果、甚至手打错别字里稳定地“浮上来”。清洗、上下文锚定、服务端兜底验证,三者缺一不可——少一步,用户就会觉得“这功能又抽风了”。



















