正则重复分组捕获多余字符:如何排除逗号与右括号?
正则表达式重复分组捕获去逗号和右括号问题
问题背景
使用正则表达式进行重复分组捕获时,后续捕获结果中混入了逗号或右括号,需要修正正则以避免此类情况。
当前正则表达式
(?<name1>\?\?\$.*)\s\((?<type1>\w+)\s(?<conv>\w+)\s(?<name2>\w+:?:?)+<(?<type2>[\w\s]+)>\((?<args>.+?(?=[,)]))+\)
输入示例
??$PlotBarGroups@C@ImPlot@@YAXQBQBDPBCHHNNH@Z (void __cdecl ImPlot::PlotBarGroups<signed char>(char const * const * const,signed char const *,int,int,double,double,int)) ??$PlotBarGroups@E@ImPlot@@YAXQBQBDPBEHHNNH@Z (void __cdecl ImPlot::PlotBarGroups<unsigned char>(char const * const * const,unsigned char const *,int,int,double,double,int)) ??$PlotBarGroups@F@ImPlot@@YAXQBQBDPBFHHNNH@Z (void __cdecl ImPlot::PlotBarGroups<short>(char const * const * const,short const *,int,int,double,double,int)) ??$PlotBarGroups@G@ImPlot@@YAXQBQBDPBGHHNNH@Z (void __cdecl ImPlot::PlotBarGroups<unsigned short>(char const * const * const,unsigned short const *,int,int,double,double,int)) ??$PlotBarGroups@H@ImPlot@@YAXQBQBDPBHHHNNH@Z (void __cdecl ImPlot::PlotBarGroups<int>(char const * const * const,int const *,int,int,double,double,int)) ??$PlotBarGroups@I@ImPlot@@YAXQBQBDPBIHHNNH@Z (void __cdecl ImPlot::PlotBarGroups<unsigned int>(char const * const * const,unsigned int const *,int,int,double,double,int)) ??$PlotBarGroups@M@ImPlot@@YAXQBQBDPBMHHNNH@Z (void __cdecl ImPlot::PlotBarGroups<float>(char const * const * const,float const *,int,int,double,double,int)) ??$PlotBarGroups@N@ImPlot@@YAXQBQBDPBNHHNNH@Z (void __cdecl ImPlot::PlotBarGroups<double>(char const * const * const,double const *,int,int,double,double,int)) ??$PlotBarGroups@_J@ImPlot@@YAXQBQBDPB_JHHNNH@Z (void __cdecl ImPlot::PlotBarGroups<__int64>(char const * const * const,__int64 const *,int,int,double,double,int)) ??$PlotBarGroups@_K@ImPlot@@YAXQBQBDPB_KHHNNH@Z (void __cdecl ImPlot::PlotBarGroups<unsigned __int64>(char const * const * const,unsigned __int64 const *,int,int,double,double,int))
实际捕获结果
signed char char const * const * const ,signed char const * ,int ,int ,double ,double ,int )
预期捕获结果
signed char char const * const * const signed char const * int int double double int
修正方案
问题出在(?<args>.+?(?=[,)]))+这个重复捕获分组上:每次匹配时会把参数前的逗号也包含进去,且最后一次匹配误捕了右括号。
修改思路:用非捕获组处理参数间的逗号分隔符,避免逗号进入捕获组;明确参数匹配的起始位置,跳过分隔符后再捕获参数内容。
修正后的正则表达式:
(?<name1>\?\?\$.*)\s\((?<type1>\w+)\s(?<conv>\w+)\s(?<name2>\w+:?:?)+<(?<type2>[\w\s]+)>\((?<args>.+?(?=[,)]))(?:,\s*(?<args>.+?(?=[,)]))*\)
关键改动说明
将原有的(?<args>.+?(?=[,)]))+替换为(?<args>.+?(?=[,)]))(?:,\s*(?<args>.+?(?=[,)]))*:
- 第一个
(?<args>.+?(?=[,)]))捕获第一个参数(无前缀逗号); (?:,\s*(?<args>.+?(?=[,)]))*用非捕获组匹配逗号+可选空格,再捕获后续参数,确保逗号不会被纳入args捕获组;- 最终匹配到所有参数时,每个
args捕获组的内容都不会包含逗号或右括号。
内容的提问来源于stack exchange,提问作者aybe
相关产品推荐
相关产品推荐

