如何基于交换机端口号列表生成带包含/排除规则的指定格式表达式
交换机端口规则表达式生成方案
核心规则逻辑
你提供的表达式规则本质是按端口的十位数值分组匹配,格式Port X[!(排除个位范围)]中,X为端口十位数值,中括号内标注该十位下需要排除的个位区间,最终匹配任意一条Port规则的端口即为包含状态。
生成步骤
- 第一步:将所有需要包含的端口按十位数值分组,归集每个十位下需要保留的个位
- 第二步:确定每个十位对应的合法个位范围(比如整体合法范围是1-19时,十位1对应的合法个位为0-9;整体合法范围是40-45时,十位4对应的合法个位为0-5)
- 第三步:对每个十位分组,计算「合法个位范围」和「需保留个位列表」的差集,该差集就是需要标注排除的个位
- 第四步:将每个十位的排除个位合并为连续区间的字符串,拼接为
Port X[!(排除区间)]格式,多个规则用|分隔后外层套括号,末尾加*即可得到最终规则
代码实现示例(Python)
from collections import defaultdict def generate_port_rule(include_ports: list[int], valid_ranges: list[tuple[int, int]]) -> str: # 按十位分组归集需要保留的个位 ten_unit_map = defaultdict(set) for port in include_ports: ten = port // 10 unit = port % 10 ten_unit_map[ten].add(unit) rule_segments = [] for ten, reserved_units in ten_unit_map.items(): # 计算当前十位对应的所有合法个位 valid_units = set() for range_start, range_end in valid_ranges: range_ten_start = range_start // 10 range_ten_end = range_end // 10 if range_ten_start <= ten <= range_ten_end: unit_start = range_start % 10 if ten == range_ten_start else 0 unit_end = range_end % 10 if ten == range_ten_end else 9 valid_units.update(range(unit_start, unit_end + 1)) # 求差集得到需要排除的个位 exclude_units = sorted(valid_units - reserved_units) if not exclude_units: # 没有需要排除的个位,不需要加中括号 rule_segments.append(f"Port {ten}") continue # 把离散的排除个位合并为连续区间字符串 exclude_intervals = [] left = right = exclude_units[0] for num in exclude_units[1:]: if num == right + 1: right = num else: exclude_intervals.append(f"{left}-{right}" if left != right else f"{left}") left = right = num exclude_intervals.append(f"{left}-{right}" if left != right else f"{left}") # 拼接当前十位的规则片段 exclude_part = f"[!({' | '.join(exclude_intervals)})]" rule_segments.append(f"Port {ten}{exclude_part}") # 拼接最终完整规则 return f"({' | '.join(rule_segments)})*" # 示例调用测试 if __name__ == "__main__": # 示例参数:包含端口1、3、44,合法端口范围1-19、40-45 result = generate_port_rule(include_ports=[1,3,44], valid_ranges=[(1,19), (40,45)]) print(result) # 输出结果:(Port 1[!(0-2 | 4-9)] | Port 4[!(0-3 | 5)])*
内容的提问来源于stack exchange,提问作者StackExchangeGuy
相关产品推荐
相关产品推荐

