带Unicode标志的JavaScript正则表达式否定字符类匹配异常
问题原因与解释
这是旧版本JavaScript正则引擎的bug,在Firefox 103、Chromium 103这类较早版本中,u标志的处理存在不一致:
- 单独使用
/[^|]$/u时,引擎能正确识别[^|]匹配完整的Unicode码点(比如𭵴),且$锚点对应字符串末尾,因此/[^|]$/u.test('𭵴')返回true。 - 但当正则前有其他匹配项(比如
\|)时,引擎错误地将[^|]视为匹配单个UTF-16代理单元,而非完整Unicode码点:- 先匹配
|(字符串第1个UTF-16单元); - 尝试用
[^|]匹配第2个代理单元\uD877; - 检查
$是否在该单元之后(字符串第2个单元位置),但实际字符串末尾在第3个单元位置,因此匹配失败,返回false。
- 先匹配
解决办法
- 若场景中只需排除
|,可用./u替代[^|],即正则改为/\|.$/u; - 使用Unicode属性转义明确匹配任意非
|的Unicode码点:/\|[\p{Any}&&[^|]]$/u; - 升级浏览器到更新版本,这类bug已被修复。
内容的提问来源于stack exchange,提问作者Danny Lin
相关产品推荐
相关产品推荐

