正则匹配短代码:兼容含/无参数场景,区分JSON数组括号
解决正则匹配带嵌套参数/无参数短代码的问题
我来帮你搞定这个正则的问题!你的核心需求是同时兼容带嵌套JSON参数和无参数的短代码,原正则的问题在于它强制要求参数部分必须存在,而且没法处理嵌套的方括号,导致无参数时匹配出错。
问题分析
原正则 /^\~([a-z]+::)([a-z\_\-]+)([^\~]+)\~/i 里的 ([^\~]+) 是贪婪匹配所有非~的字符,而且是必填项——但无参数的短代码里,插件名称后面直接就是~,这部分就匹配失败,进而导致插件名称被错误拆分。另外,这个正则也没法处理嵌套的[](比如你示例里JSON数组里的嵌套结构),因为它只会匹配到第一个]就停止了。
解决方案:支持嵌套括号的可选参数正则
我们需要调整正则,让参数部分变成可选,同时用递归匹配来处理嵌套的方括号,这样不管有没有参数,也不管参数里有多少层嵌套,都能正确捕获。
最终的正则表达式如下:
/^\~([A-Z]+::)([a-z_\-]+)(?:\[((?:[^[\]]|(?R))*)\])?\~/i
正则各部分解释
^\~:匹配短代码开头的~([A-Z]+::):捕获插件前缀(比如PLUGIN::),i修饰符保证不区分大小写([a-z_\-]+):捕获插件名称,支持字母、下划线和连字符(?:\[((?:[^[\]]|(?R))*)\])?:这是关键的可选参数部分:?:表示这是一个非捕获组,只是用来包裹参数结构\[和\]匹配参数的外层方括号((?:[^[\]]|(?R))*):捕获方括号内的所有内容,其中:[^[\]]匹配非方括号的普通字符(?R)递归匹配整个正则模式,用来处理嵌套的方括号结构
?表示整个参数部分是可选的(无参数时这部分直接不匹配)
\~:匹配短代码结尾的~i:不区分大小写修饰符
测试示例
下面是PHP代码的测试效果,两种情况都能正确匹配:
// 无参数短代码测试 $str1 = '~PLUGIN::name_test~'; preg_match('/^\~([A-Z]+::)([a-z_\-]+)(?:\[((?:[^[\]]|(?R))*)\])?\~/i', $str1, $matches1); print_r($matches1); // 输出结果: // Array // ( // [0] => ~PLUGIN::name_test~ // [1] => PLUGIN:: // [2] => name_test // ) // 带嵌套参数短代码测试 $str2 = '~PLUGIN::name_of_plugin[{ "category":"whatever", "test":[{ "name":"Title Something", "desc":"123123-A", "result":"Confirmation", "conforms":"true", "mass_spec":"true" }] }]~'; preg_match('/^\~([A-Z]+::)([a-z_\-]+)(?:\[((?:[^[\]]|(?R))*)\])?\~/i', $str2, $matches2); print_r($matches2); // 输出结果里的[3]会完整捕获嵌套的JSON内容,你可以直接用json_decode解析它
这样不管是无参数还是带复杂嵌套参数的短代码,都能正确拆分出前缀、插件名称和参数内容,完全不需要临时拼接的方案。
内容的提问来源于stack exchange,提问作者Rasclatt
相关产品推荐
相关产品推荐

