VBA正则匹配含mes/ar/inv文件名 排除beneficiario规则失效问题
问题说明
待匹配文件名列表:
- qryReservasxMesxAR_Inv 2021 09.xls
- qryReservasxMesAR_Inv 2021 10.xls
- qryReservasxMesAR_Inv 2021 11.xls
- qryReservasxMesSob 2021 12.xls
- qryReservasxMesxBeneficiarioAR_Inv 2021 07.xls
- qryReservasxMesxBeneficiarioAR_Inv 2021 08.xls
- qryReservasxMesxBeneficiarioAR_Inv 2021 09.xls
- qryReservasxMesxBeneficiarioSob 2021 10.xls
- qryReservasxMesxBeneficiarioSob 2021 11.xls
匹配规则:筛选同时包含mes、ar、inv三个关键词,且不包含beneficiario关键词的文件。因文件名分隔符不固定(存在x、_等多种分隔符),无法使用固定格式匹配。
原有失效VBA正则代码如下:
Dim RegexUno As Object: Set RegexUno = New RegExp With RegexUno .Pattern = "mes.*(?!beneficiario).*ar.*inv" .Global = False .IgnoreCase = True End With
原正则预期逻辑:匹配mes后接任意字符,若中间出现beneficiario则匹配失败,后续继续匹配ar、inv关键词,但实际测试时无法正确排除带beneficiario的文件。
失效原因
原正则的负向预查位置错误:正则中.*为贪婪匹配模式,会直接匹配mes到ar之间的所有字符(包含beneficiario),此时负向预查的校验位置已经在beneficiario之后,无法检测到该关键词,排除逻辑完全失效。
可用方案
方案1:不限制关键词顺序(适配性更强)
直接替换正则Pattern即可,不需要修改其他VBA配置:
^(?=.*mes)(?=.*ar)(?=.*inv)(?!.*beneficiario).*$
逻辑说明:
- 三个正向预查分别校验全字符串存在
mes、ar、inv三个关键词,不限制三个词的出现顺序 - 负向预查校验全字符串不存在
beneficiario关键词 - 不限制关键词之间的字符类型,完全适配不固定的文件名分隔符
对应完整VBA代码:
Dim RegexUno As Object: Set RegexUno = New RegExp With RegexUno .Pattern = "^(?=.*mes)(?=.*ar)(?=.*inv)(?!.*beneficiario).*$" .Global = False .IgnoreCase = True End With
测试匹配结果:
- 命中文件:
qryReservasxMesxAR_Inv 2021 09.xls、qryReservasxMesAR_Inv 2021 10.xls、qryReservasxMesAR_Inv 2021 11.xls - 所有带
Sob(缺失inv)、带beneficiario的文件全部被排除,符合预期。
方案2:严格保留mes在前的匹配顺序
如果需要严格保证mes出现在ar、inv之前,贴合最初的正则设计逻辑,可使用Pattern:
mes(?:(?!beneficiario).)*ar.*inv
逻辑说明:把负向预查嵌入mes之后的字符匹配规则中,每匹配mes后的一个字符,就先校验后续内容不是beneficiario,避免贪婪匹配直接跳过关键词导致校验失效。
内容的提问来源于stack exchange,提问作者Irving Pérez
相关产品推荐
相关产品推荐

