如何修改现有正则表达式实现嵌套动态命令的递归匹配解析
问题原因
你当前使用的非贪婪匹配.*?遇到第一个]就会终止匹配,天然无法处理嵌套的方括号结构,这类嵌套场景属于上下文无关文法范畴,需要用到正则引擎的递归匹配能力(主流PCRE兼容正则引擎均支持,例如PHP、Python3、Java 9+等环境都可以直接用)。
修改后的正则表达式
@((lookup|resolve|count|href|currencify)\[(?:[^[\]]+|(?R))*\])
语法说明
- 开头的
@和命令名匹配逻辑和你原有正则完全一致,兼容原有非嵌套场景的匹配结果 - 方括号内部匹配逻辑替换为
(?:[^[\]]+|(?R))*:[^[\]]+匹配所有不包含方括号的普通文本内容(?R)是PCRE递归语法,代表递归套用整个正则的匹配规则,遇到嵌套的@命令[xxx]结构时会自动深度匹配- 外层
*表示方括号内部可以由多段普通文本/嵌套命令组合而成
内外层命令提取方法
- 先用上述正则扫描原始文本,提取所有最外层的命令片段
- 对每个提取到的外层命令的方括号内部内容,再次用同样的正则递归扫描,即可提取到所有内层嵌套的命令
兼容方案(正则不支持递归时使用)
如果你的开发环境正则引擎不支持递归语法,可以用手动栈计数的方式实现匹配:
- 遍历字符串定位到
@命令[的起始位置后,初始化栈计数为1 - 向后遍历每个字符,遇到
[就栈计数+1,遇到]就栈计数-1 - 当栈计数回到0时,当前位置就是和起始
[对应的闭合],截取中间内容即可得到完整的命令参数
内容的提问来源于stack exchange,提问作者Sash
相关产品推荐
相关产品推荐

