PowerShell如何对包含正则/通配符的白名单数组执行匹配校验
优化实现方案
你可以通过预处理白名单分层匹配的方式大幅提升比对性能,不需要每次全量遍历所有白名单规则,核心思路是把白名单规则拆成精确匹配和模式匹配两类分别处理:
- 普通精确匹配的规则存入
HashSet,查询复杂度为O(1),不需要做任何正则运算 - 通配符、正则类的规则提前编译成正则对象,避免每次匹配重复解析产生的开销
步骤1:预处理白名单(仅需执行一次)
# 初始化两个集合分别存精确匹配项和预编译正则 $ordinaryWhitelist = [System.Collections.Generic.HashSet[string]]::new() $regexWhitelist = [System.Collections.Generic.List[regex]]::new() foreach ($rule in $whitelist) { # 规则类型判断逻辑可根据你的实际约定调整,示例支持三种规则: # 1. 用/包裹的原生正则:如 /^Microsoft 365.*$/ # 2. 带通配符的字符串:如 *Chrome* # 3. 普通精确匹配字符串:如 "钉钉" if ($rule -match '^/(.+)/$') { # 提取原生正则内容并编译 $compiledRegex = [regex]::new($matches[1], [System.Text.RegularExpressions.RegexOptions]::Compiled) $regexWhitelist.Add($compiledRegex) } elseif ($rule -match '[*?]') { # 通配符规则转成正则后编译 $regexPattern = '^' + [regex]::Escape($rule).Replace('\*', '.*').Replace('\?', '.') + '$' $compiledRegex = [regex]::new($regexPattern, [System.Text.RegularExpressions.RegexOptions]::Compiled) $regexWhitelist.Add($compiledRegex) } else { # 普通字符串直接加入哈希集合 $ordinaryWhitelist.Add($rule) | Out-Null } }
步骤2:替换原有比对逻辑
# 直接收集输出替代+=拼接数组,避免数组反复重建的性能损耗 $whitelist_builder = $xxxxx | ForEach-Object { $installed_software = $_ # 优先走精确匹配,90%以上的请求这一步就能出结果 if ($ordinaryWhitelist.Contains($installed_software)) { return } # 精确匹配未命中再遍历正则规则,只要命中任意一条就算白名单内 foreach ($reg in $regexWhitelist) { if ($reg.IsMatch($installed_software)) { return } } # 所有规则都未命中,加入结果集 $installed_software }
性能说明
如果你的白名单中普通精确匹配项占比超过70%,这套方案的性能比全量遍历正则匹配高3~10倍;哪怕你的白名单全是正则规则,提前编译也能比每次用-match临时解析正则快一倍以上。如果你的白名单规则总数少于1000条,哪怕全量遍历正则的性能也完全满足普通业务场景需求,不需要做额外优化。
内容的提问来源于stack exchange,提问作者Tim Brigham
相关产品推荐
相关产品推荐

