我是Python的新手,请原谅我问一些愚蠢的事情。 从文本文件中,将字典用作通过/阻止过滤器。 文本文件包含地址和一个块或一个允许的名称,例如“ 002029568,allow”或“ 0011 *,allow”(不带引号)。 搜索输入是带有完整代码的字符串,例如“ 001180000”。 如何评估搜索项是否在词典中并使其与“ 0011 *,allow”行匹配? 非常感谢您的努力!
过滤器词典的制作方法是:
def loadFilterDict(filename):
global filterDict
try:
with open(filename, "r") as text_file:
lines = text_file.readlines()
for s in lines:
fields = s.split(',')
if len(fields) == 2:
filterDict[fields[0]] = fields[1].strip()
text_file.close()
except:
pass
检查代码(ccode)是否在字典中:
if ccode in filterDict:
if filterDict[ccode] in ['block']:
continue
else:
if filterstat in ['block']:
continue
过滤器文件如下:
002029568,允许 000923993,允许 0011 *,允许
答案 0 :(得分:2)
如果文件中的通配符条目具有固定长度(例如,您只需要支持0011*,allow
之类的行,而无需支持00110*,allow
或0*,allow
之类的行或任何其他任意数字位数紧跟*
之后),您可以使用嵌套字典,其中外键是通配符条目的已知部分。
d = {'0011': {'001180000': 'value', '001180001': 'value'}}
然后,当您解析文件并到达行0011*,allow
时,您无需进行任何匹配。您要做的就是检查'0011'
是否存在。粗暴的例子:
d = {'0011': {'001180000': 'value', '001180001': 'value'}}
line = '0011*,allow'
prefix = line.split(',')[0][:-1]
if prefix in d:
# there is a "match", then you can deal with all the entries that match,
# in this case the items in the inner dictionary
# {'001180000': 'value', '001180001': 'value'}
print('match')
else:
print('no match')
如果您确实需要支持任意长度的通配符条目,则必须诉诸循环遍历字典(因此击败使用字典开头的点):
d = {'001180000': 'value', '001180001': 'value'}
line = '0011*,allow'
prefix = line.split(',')[0][:-1]
for k, v in d.items():
if k.startswith(prefix):
# found matching key-value pair
print(k, v)
答案 1 :(得分:2)
如果您可以使用re
,则不必担心通配符,而让re.match
为您完成艰苦的工作:
# Rules input (this could also be read from file)
lines = """002029568,allow
0011*,allow
001180001,block
"""
# Parse rules from string
rules = []
for line in lines.split("\n"):
line = line.strip()
if not line:
continue
identifier, ruling = line.split(",")
rules += [(identifier, ruling)]
# Get rulings for specific number
def rule(number):
from re import match
rulings = []
for identifier, ruling in rules:
# Replace wildcard with regex .*
identifier = identifier.replace("*", ".*")
if match(identifier, number):
rulings += [ruling]
return rulings
print(rule("001180000"))
print(rule("001180001"))
哪些印刷品:
['allow']
['allow', 'block']
该函数将返回规则列表。它们的顺序与配置行中显示的顺序相同。因此,您可以轻松选择最感兴趣的一项或最后一项。
或者,如果您可以假设没有两个裁定会干涉,则过早打破循环。
示例:
001180000
仅与0011*,allow
匹配,因此唯一适用的规则是allow
。001180001
首先与0011*,allow
匹配,所以您将像以前一样获得allow
。但是,它也与001180001,block
相匹配,因此block
也将添加到规则中。