Python如何通过子串匹配精简含通配符的域名列表?
Python域名精简汇总实现方案
规则说明
我们首先明确PAC场景下的域名覆盖规则:
- 通配符
*仅可匹配域名同一层级的任意内容,不可跨.匹配 - 当普通域名完全符合某条带通配符的规则时,该普通域名可被精简删除
- 若多条带通配符的规则之间存在覆盖关系,仅保留最泛化的规则即可
实现思路
- 对输入域名先做去重处理,避免无效计算
- 按域名拆分后的段数分组,不同段数的域名无法互相覆盖,可独立处理
- 同组内优先处理通配符更多的泛化规则,后续检查每一条域名是否被已保留的规则覆盖,未被覆盖的才加入结果集
代码实现
from collections import defaultdict def is_covered(domain: str, rule: str) -> bool: """判断域名是否被指定的通配符规则覆盖""" domain_parts = domain.split('.') rule_parts = rule.split('.') # 段数不同无法覆盖 if len(domain_parts) != len(rule_parts): return False # 逐段匹配 for d_part, r_part in zip(domain_parts, rule_parts): if r_part != '*' and d_part != r_part: return False return True def simplify_domains(domains: list[str]) -> list[str]: """精简域名列表,移除可被通配符规则覆盖的域名""" # 去重 unique_domains = list(set(domains)) # 按域名段数分组 domain_groups = defaultdict(list) for d in unique_domains: part_count = len(d.split('.')) domain_groups[part_count].append(d) result = [] for group in domain_groups.values(): kept = [] # 按通配符数量降序排序,泛化程度高的规则优先保留 sorted_group = sorted(group, key=lambda x: -x.count('*')) for domain in sorted_group: # 检查当前域名是否已被保留的规则覆盖 covered = any(is_covered(domain, rule) for rule in kept) if not covered: kept.append(domain) result.extend(kept) # 按域名层级排序,输出更规整 result.sort(key=lambda x: (len(x.split('.')), x)) return result
测试验证
使用你提供的输入测试:
if __name__ == "__main__": input_domains = [ "www.example.com", "*.example.com", "example.com", "myserver.example.com", "server.*.example2.com", "server.mydomain1.example2.com", "server.mydomain2.example2.com", "server.mydomain3.example2.com", "example2.com" ] simplified = simplify_domains(input_domains) for d in simplified: print(d)
输出结果:
example.com example2.com *.example.com server.*.example2.com
完全符合预期效果,且整个实现无需复杂正则,逻辑清晰易扩展,符合Python编码规范。
内容的提问来源于stack exchange,提问作者TheScriptGuy
相关产品推荐
相关产品推荐

