【发布时间】:2017-01-23 11:39:18
【问题描述】:
我们有 10-20 个遵循这种基本格式的字典,键是要分配的值,值是正则表达式:
osTypeRE = collections.OrderedDict([
('WINDOWS', re.compile('^.*(windows|WIN2008|WIN2003).*$', re.MULTILINE+re.IGNORECASE)),
('LINUX/UNIX', re.compile('^.*(unix|linux|ubuntu|red hat|redhat|RHEL|CentOS|CENT OS|Debian|SLES|SUSE|freebsd|free bsd|AIX|Solaris|SunOS).*$', re.MULTILINE+re.IGNORECASE)),
('MAC', re.compile('^.*(mac os x).*$', re.MULTILINE+re.IGNORECASE)),
('STRATUS VOS', re.compile('^.*(VOS|Stratus).*$', re.MULTILINE+re.IGNORECASE)),
('MAINFRAME', re.compile('^.*(OS400|AS400).*$', re.MULTILINE+re.IGNORECASE)),
('CISCO IOS', re.compile('^.*(IOS).*$', re.MULTILINE+re.IGNORECASE)),
('NETWARE/OES', re.compile('^.*(NETWARE|OES|Open Enterprise Server).*$', re.MULTILINE+re.IGNORECASE)),
('OPENVMS', re.compile('^.*(VMS).*$', re.MULTILINE+re.IGNORECASE)),
('HYPERVISOR', re.compile('^.*(ESX).*$', re.MULTILINE+re.IGNORECASE)),
('HP NONSTOP', re.compile('^.*(NONSTOP|Tandem|NON STOP).*|.*(H06.20).*$', re.MULTILINE+re.IGNORECASE)),
('EMBEDDED', re.compile('^.*(QNX).*$', re.MULTILINE+re.IGNORECASE))
])
事实证明,这些类型的字典非常有用,因为它使我们能够将来自多个管理系统的计算机信息标准化,以便随后对信息进行协调。
唯一的问题是它太慢了。这是我们使用这种类型的字典来规范化我们的数据的函数:
def reg_lookup(lookup, re_dict):
value = "INDETERMINATE"
for key, reg_ex in re_dict.items():
matched = reg_ex.search(lookup)
if matched:
value = key.upper()
break
return value
所以基本上,我们循环遍历字典值(它们是正则表达式),当我们找到匹配项时,我们获取键并成为新的标准化值。
但是由于我们在字典中循环,我们正在失去与字典类型哈希表相关的速度。但是我们要如何克服呢?我可以简单地交换这些字典中的键值对吗?但是,我的 reg_lookup 函数需要如何更改,它会更快吗?
另一个示例字典:
osVerRE = collections.OrderedDict([
('WINDOWS', collections.OrderedDict([
('WINDOWS SERVER 2000 SERIES', re.compile('^(?=.*WINDOWS)(?=.*SERVER)(?=.*2000).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS SERVER 2003 ENTERPRISE', re.compile('^(?=.*WINDOWS)(?=.*SERVER|.* SR )(?=.*2003)(?=.*ENTERPRISE|.* Ent).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS SERVER 2003 STANDARD', re.compile('^(?=.*WINDOWS)(?=.*SERVER)(?=.*2003)(?=.*STANDARD|.*STD).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS SERVER 2003 SERIES', re.compile('^(?=.*WINDOWS)(?=.*SERVER)(?=.*2003).*|(?=.*WIN2003).*|(?=.*Windows)(?=.*SERVER)(?=.*2k3).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS SERVER 2008 ENTERPRISE', re.compile('^(?=.*WINDOWS)(?=.*SERVER)(?=.*2008)(?=.*ENTERPRISE|.* ENT).*|(?=.*WINDOWS)(?=.*SERVER)(?=.*2K8)(?=.*ENTERPRISE|.* ENT).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS SERVER 2008 STANDARD', re.compile('^(?=.*WINDOWS)(?=.*SERVER)(?=.*2008)(?=.*STANDARD|.*STD).*|(?=.*WINDOWS)(?=.*SERVER)(?=.*2K8)(?=.*STANDARD|.*STD).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS SERVER 2008 DATACENTER', re.compile('^(?=.*WINDOWS)(?=.*SERVER)(?=.*2008)(?=.*DATACENTER).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS SERVER 2008 SERIES', re.compile('^(?=.*WINDOWS)(?=.*SERVER)(?=.*2008).*|(?=.*WINDOWS)(?=.*SERVER)(?=.*2K8).*|(?=.*WIN2008).*|(?=.*WINDOWS 2K8 R2).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS SERVER 2012 DATACENTER', re.compile('^(?=.*WINDOWS)(?=.*SERVER)(?=.*2012)(?=.*DATACENTER).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS SERVER 2012 STANDARD', re.compile('^(?=.*WINDOWS)(?=.*SERVER)(?=.*2012)(?=.*STANDARD).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS SERVER 2012 SERIES', re.compile('^(?=.*WINDOWS)(?=.*SERVER)(?=.*2012).*|(?=.*WINDOWS)(?=.*2012 R2).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS NT 4.0', re.compile('^(?=.*WINDOWS)(?=.*NT)(?=.*4\.0).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS XP PROFESSIONAL', re.compile('^(?=.*WINDOWS)(?=.*XP)(?=.*PROFESSIONAL).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS 10 PROFESSIONAL', re.compile('^(?=.*WINDOWS)(?=.*10)(?=.*PRO).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS 7 ENTERPRISE', re.compile('^(?=.*WINDOWS)(?=.*7)(?=.*ENTERPRISE).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS 7 PROFESSIONAL', re.compile('^(?=.*WINDOWS)(?=.*7)(?=.*PROFESSIONAL).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS 7 ULTIMATE', re.compile('^(?=.*WINDOWS)(?=.*7)(?=.*ULTIMATE).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS SERVER LINE', re.compile('^(?=.*WINDOWS)(?=.*SERVER).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS XP LINE', re.compile('^(?=.*WINDOWS)(?=.*XP).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS 7 LINE', re.compile('^(?=.*WINDOWS)(?=.*7).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS 8 LINE', re.compile('^(?=.*WINDOWS)(?=.*8).*$', re.MULTILINE+re.IGNORECASE)),
('WINDOWS 10 LINE', re.compile('^(?=.*WINDOWS)(?=.*10).*$', re.MULTILINE+re.IGNORECASE))
])),
.
.
.
【问题讨论】:
-
好吧,如果你必须循环,你就必须循环......为什么首先要使用字典?
-
如果您仍然需要检查每个表达式是否匹配,有什么区别?
-
@juanpa.arrivillaga:你不必循环,因为词法分析器也可以完成这些任务,并且在要解析的内容长度上工作,而不是潜在标记的数量。
-
好吧,如果你要循环,循环遍历一个元组列表。
-
为什么所有的正则表达式都使用
^.*和.*$?这些是多余的,re.MULTILINE标志也是如此。您只需要查找是否存在特定单词(或一组单词中的一个)。
标签: python regex dictionary hashtable