JS正则匹配含换行的多行对象内容失效如何修复
问题根因
三个问题导致匹配失败:
- JS正则默认模式下,元字符
.不会匹配换行符(\n、\r),跨多行的对象内容会直接中断匹配 - 你使用
new RegExp构造正则时,误将正则字面量的结尾分隔符/写进了匹配规则里,但待匹配内容中}后根本不存在/字符 - 原规则没有匹配对象结尾的分号
;,就算解决换行问题也无法完整捕获到预期的整段对象内容
修改方案
方案1:ES2018+ 环境推荐写法(使用dotAll模式)
给正则增加s修饰符开启dotAll模式,让.可以匹配包括换行在内的所有字符,移除误写的/,补全结尾分号的匹配,同时把需要提取的大括号整体放入捕获组:
// 构造函数写法 const test = new RegExp('var _0x((?=\\d+[A-Za-z]+[\\w@]+|[a-zA-Z]+[\\w@]+)[\\w@]{6}) = ({.*?};)', 'gms'); const res = test.exec(script); // 提取到的预期对象内容存放在 res[2] 中
如果习惯写正则字面量,写法更简洁不需要额外转义反斜杠:
const test = /var _0x((?=\d+[A-Za-z]+[\w@]+|[a-zA-Z]+[\w@]+)[\w@]{6}) = ({.*?};)/gms; const res = test.exec(script);
方案2:低版本环境兼容写法
如果运行环境不支持s修饰符(IE、部分低版本移动端Webview),将匹配内容的.替换为[\s\S](匹配所有空白+非空白字符,等价于匹配任意字符包括换行),不需要新增s修饰符:
// 构造函数写法 const test = new RegExp('var _0x((?=\\d+[A-Za-z]+[\\w@]+|[a-zA-Z]+[\\w@]+)[\\w@]{6}) = ({[\\s\\S]*?};)', 'gm'); const res = test.exec(script); // 提取到的预期对象内容存放在 res[2] 中
补充说明
- 上述规则使用非贪婪匹配
*?,会匹配到距离起始位置最近的一个};作为结束,对你给出的样例输入可以完全匹配到预期结果 - 如果后续遇到对象内部嵌套对象/函数的场景,非贪婪匹配会提前终止,这种场景需要写专门的括号计数匹配逻辑,不能简单用非贪婪匹配处理
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

