PHP正则表达式:捕获重复命名递归的所有匹配项
解决PHP正则中重复命名递归的所有匹配项捕获问题
嘿,我来帮你搞定这个PHP正则的递归捕获难题!你现在的需求是要捕获递归结构里所有重复的命名组匹配项,默认情况下PHP的PCRE会覆盖之前的匹配值,所以得调整正则写法和匹配方式。
核心问题分析
PHP的PCRE引擎默认情况下,同一个命名捕获组如果被多次匹配(不管是递归还是循环),最后一次匹配会覆盖之前的结果。要捕获所有实例,我们需要结合递归子组定义、(?J)修饰符(允许重复命名组)和正确的preg_match_all参数。
调整后的正则表达式
针对你给出的原正则,我调整了结构来支持递归捕获所有parameter_set实例:
/(?J) \( (?# Expression start) (?<optgroup_start>\() (?# Parameter group start - 递归捕获所有参数项) (?<parameter_set>\[(?:[a-z0-9]+)\]) (?:,*\s*(?¶meter_set))* (?<optgroup_end>\)) ,*\s* (?: "(?<options_scalar>.*)" | (?<options_complex>.*) ) | (?<simple_parameter_set> (?<parameter_set>\[(?:[a-z0-9]+)\]) (?:,*\s*(?¶meter_set))* ) /xg
关键修改点:
- 添加
(?J)修饰符:允许正则中重复使用同一个命名组名(比如parameter_set在两个分支都出现)。 - 重构
parameter_set为递归结构:(?<parameter_set>\[(?:[a-z0-9]+)\])(?:,*\s*(?¶meter_set))*,这样每个[xxx]都会被单独捕获为parameter_set的一个实例。 - 添加
/x修饰符:忽略正则里的空白和注释,让结构更清晰;/g全局匹配,捕获所有符合的结构。
如何捕获所有匹配项
使用preg_match_all配合PREG_PATTERN_ORDER参数,这样命名组的所有捕获实例会被整理成数组:
$pattern = '/(?J)\( (?# Expression start) (?<optgroup_start>\() (?# Parameter group start - 递归捕获所有参数项) (?<parameter_set>\[(?:[a-z0-9]+)\]) (?:,*\s*(?¶meter_set))* (?<optgroup_end>\)) ,*\s* (?: "(?<options_scalar>.*)" | (?<options_complex>.*) ) | (?<simple_parameter_set> (?<parameter_set>\[(?:[a-z0-9]+)\]) (?:,*\s*(?¶meter_set))* )/xg'; $subject = '([foo], [bar], [baz]), "opt1" | ([qux], [quux])'; preg_match_all($pattern, $subject, $matches, PREG_PATTERN_ORDER); // 输出所有parameter_set的捕获实例 print_r($matches['parameter_set']);
这段代码会输出所有匹配到的[foo]、[bar]、[baz]、[qux]、[quux],每个都是parameter_set数组里的单独元素。
兼容旧版本PHP(<7.3)
如果你还在使用PHP 7.3之前的版本,(?J)修饰符不被支持,那可以改用匿名子组+全局匹配的方式,或者给不同分支的组起不同名字,然后合并结果:
/ \( (?<optgroup_start>\() (?<param1>\[(?:[a-z0-9]+)\]) (?:,*\s*(?<param2>\[(?:[a-z0-9]+)\]))* (?<optgroup_end>\)) ,*\s* (?: "(?<options_scalar>.*)" | (?<options_complex>.*) ) | (?<simple_param1>\[(?:[a-z0-9]+)\]) (?:,*\s*(?<simple_param2>\[(?:[a-z0-9]+)\]))* /xg
然后在PHP里合并$matches['param1']、$matches['param2']、$matches['simple_param1']等数组,得到所有捕获项。不过这种方式不够优雅,还是建议升级到PHP 7.3+使用(?J)方案。
内容的提问来源于stack exchange,提问作者Serhii Matrunchyk
相关产品推荐
相关产品推荐

