正则匹配含嵌套大括号的报文:如何捕获完整匹配项
解决SWIFT报文嵌套大括号的正则匹配问题
问题场景
要匹配的SWIFT报文示例:
{1:A01ABCDEFGHIJKL1234567890}{2:01234567890123ABCDEFGHIJKL12345678901234567890A}{3:{108:ABCDEFGHIJK0123}}{4: :20:ABCDEFGHIJK/01234 :25:00000000000000000000 :28C:00001/00001 :60F:C230316EUR0,00 :62F:C230317EUR0,00 :64:C230317EUR0,00 :65:C230318EUR0,00 :65:C230319EUR0,00 :65:C230320EUR0,00 :65:C230321EUR0,00 :65:C230322EUR0,00 -}
原正则表达式(?<=\{)([^}]+)(?=\})无法处理嵌套大括号(如{3:{108:ABCDEFGHIJK0123}}),只能捕获到第一个}前的内容,无法匹配完整的顶级大括号内的内容。
解决方案
核心思路
需要匹配顶级大括号内的完整内容(允许包含单层嵌套的{...}),同时不递归匹配嵌套内部的内容。以下是几种适配不同正则引擎的方案:
方案1:通用单层嵌套匹配(适用于所有主流正则引擎)
\{(\d:(?:[^{}]|\{[^{}]+\})*)\}
逻辑说明:
\d:匹配以数字开头的记录标识符(如1:、3:)(?:[^{}]|\{[^{}]+\})*匹配任意非大括号字符,或者一组完整的嵌套大括号{...},重复任意次数- 最终匹配到对应的顶级闭合大括号
}
方案2:简化匹配(适配SWIFT常见结构)
如果确认SWIFT报文中仅存在单层嵌套(如组3的结构),可以用更简洁的表达式:
\{(\d:(?:[^{}]*\{[^{}]+\})?[^{}]*)\}
方案3:平衡组匹配(支持多层嵌套,适用于PCRE、.NET等引擎)
如果需要处理极少数多层嵌套的情况,可使用平衡组语法:
\{(\d:(?:[^{}]|(?R))*)\}
注:该语法仅支持支持递归匹配的正则引擎。
匹配效果
使用方案1的正则,可从测试报文中捕获到4个完整的顶级块内容:
1:A01ABCDEFGHIJKL12345678902:01234567890123ABCDEFGHIJKL12345678901234567890A3:{108:ABCDEFGHIJK0123}4:\n:20:ABCDEFGHIJK/01234\n:25:00000000000000000000\n:28C:00001/00001\n:60F:C230316EUR0,00\n:62F:C230317EUR0,00\n:64:C230317EUR0,00\n:65:C230318EUR0,00\n:65:C230319EUR0,00\n:65:C230320EUR0,00\n:65:C230321EUR0,00\n:65:C230322EUR0,00\n-
原正则问题分析
原表达式(?<=\{)([^}]+)(?=\})使用[^}]+匹配所有非}字符,遇到第一个}就终止匹配,因此无法处理嵌套大括号的场景,只能捕获到嵌套结构的前半部分。
内容的提问来源于stack exchange,提问作者Srii
相关产品推荐
相关产品推荐

