如何使用多lookbehind后向断言实现JSON数组块的格式化?
注意:本问题仅作学习用途,我明确知晓该问题在任意现代代码编辑器中都可以轻松解决。
问题描述
我十分认可正则表达式的强大功能,但始终没能完全掌握其高阶特性,尤其是环视(lookarounds)功能。我需要用正则将缩进格式化的JSON对象数组转换为紧凑的行首/行尾格式,具体需求如下:
- 原格式示例:
[ { "prop1": val1, "prop2": val2, // ...任意数量属性 }, // ...任意数量符合上述结构的对象 ]
- 预期输出格式:
[{ // 首个对象的开括号与数组左方括号相邻 // ...首个对象的所有属性 }, { // ...其余对象的所有属性 }] // 最后一个对象的闭括号与数组右方括号相邻
现有方案问题
我最初写的正则规则如下:
// 查找规则:(?<=\[\n *\{\n)(?<= {4})(.*\n)* // 替换规则:[{\n$&]
添加第二个后向断言的目的是缩减每个属性行、对象闭合与新对象开启行的缩进,但该断言添加后整个规则直接失效。
移除该断言后匹配结果近乎完美,但存在两个问题:
- 所有行的缩进没有被缩减
- 最后一个对象闭括号后的换行也被错误匹配,实际输出如下:
[{ "prop1": val1, "prop2: val2 }, { "prop1": val1, "prop2: val2 } ]
解决方案
你遇到的问题核心有两点:
- 连续的后向断言是「与」逻辑,第二个
(?<= {4})要求当前匹配位置的前4个字符必须是空格,但你的第一个后向断言匹配的是[换行后接{再换行的位置,这个位置的前缀是{\n,并不满足前4个字符都是空格的要求,所以规则直接失效。 - 不加第二个断言时
(.*\n)*会贪婪匹配到文档末尾的所有内容,包括最后一个}之后的换行和单独的]。
可以用以下规则实现需求:
查找正则
^\[\n *{\n|(^ )|\n\]$
注:规则里的
是4个空格,和你原格式的缩进量一致,可根据实际缩进量调整。
替换逻辑
- 匹配到
^\[\n *{\n的部分替换为[{ - 匹配到行首4个空格的部分删除(替换为空)
- 匹配到
\n\]$的部分替换为]
如果要写成单条正则替换,可以用分组捕获实现:
单条查找规则
(?:^\[\n *{\n|(^ )|\n\]$)
单条替换规则
$1?'':'['
注:该规则需要正则引擎支持条件替换,主流编辑器(VS Code、Sublime Text等)和调试工具都兼容该语法。
调整后即可得到完全符合预期的格式化结果。
内容的提问来源于stack exchange,提问作者Kenny83
相关产品推荐
相关产品推荐

