我有一个asn格式的文本文件,现在在此示例中在此处编写我自己的解析器,它首先为Order创建一个字典,然后进入各项,然后查看值是否不是字典,Dictionary文件中已被识别并保存在seq_list中。现在,我需要编写一个递归函数,该函数位于所有字典中并创建嵌套字典。
import re
ee='\
Module-order DEFINITIONS AUTOMATIC TAGS ::=\
BEGIN\
Order ::= SEQUENCE {\
header Order-header\
}\
Order-header ::= SEQUENCE {\
reference NumericString (SIZE (12)),\
date NumericString (SIZE (8)) -- MMDDYYYY --\
}END'
seq_list=['Order','Order-header']
condition='Order ::= SEQUENCE {\
header Order-header\
}'
def rec_fn():
ee=ee.lower()
ee=ee.replace('\n','')
for i in condition:
# Removes emty items
i=i.split(' ')
k.append(filter(None, i))
for index_content,content in enumerate(k):
for index,value in enumerate(content[1:]):
new_value=value.replace(',','')
if new_value in seq_list:
# will have the contents of all the items of the new
# dictionary found.
reg_value=re.findall(r'{0}\s*::=\s*sequence(.*?)(::=|end)'.format(new_value),ee)
sample.asn
ee=''' Module-order DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
Order ::= SEQUENCE {
header Order-header,
items SEQUENCE OF Order-line }
Order-header ::= SEQUENCE {
reference NumericString (SIZE (12)),
date NumericString (SIZE (8)) -- MMDDYYYY --,
client Client,
payment Payment-method }
Client ::= SEQUENCE {
name PrintableString (SIZE (1..20)),
street PrintableString (SIZE (1..50)) OPTIONAL,
postcode NumericString (SIZE (5)),
town PrintableString (SIZE (1..30)),
country PrintableString (SIZE (1..20)) DEFAULT "France" }
Payment-method ::= CHOICE {
check NumericString (SIZE (15)),
credit-card Credit-card,
cash NULL }
Credit-card ::= SEQUENCE {
type Card-type,
number NumericString (SIZE (20)),
expiry-date NumericString (SIZE (6)) -- MMYYYY -- }
Card-type ::= ENUMERATED {cb(0), visa(1), eurocard(2), diners(3), american-express(4)}END
答案 0 :(得分:0)
您可以使用以下递归函数:
import re
def rec_fn(asn, key):
def build_definitions(mapping, key, sequence_only=False):
if not sequence_only and (key,) in mapping:
key = (key,)
is_choice = True
else:
is_choice = False
if isinstance(mapping[key], dict):
definitions = {}
for variable, definition in mapping[key].items():
if definition in mapping or (definition,) in mapping:
definitions[variable] = build_definitions(mapping, definition, sequence_only=is_choice)
else:
definitions[variable] = definition
return definitions
else:
return mapping[key]
mapping = {}
for name, type, definition in re.findall(r'([A-Za-z-]+)\s*::=\s*(SEQUENCE|CHOICE|ENUMERATED)\s*{(.*?)}(?=\s*(?:[A-Za-z-]+\s*::=\s*(?:SEQUENCE|CHOICE|ENUMERATED)|END)\b)', asn, flags=re.DOTALL):
if type in ('SEQUENCE', 'CHOICE'):
for definitions in re.sub(r'{[^}]*}', '', definition).split(','):
definitions = re.sub(r'\bSET OF\b|\(.*\).*', '', definitions).strip().split(maxsplit=1)
if definitions:
mapping.setdefault(name if type == 'SEQUENCE' else (name,), {})[definitions[0]] = definitions[1]
elif type == 'ENUMERATED':
mapping[name] = re.findall(r'[A-Za-z-]+', definition)
return build_definitions(mapping, key)
这样(注意,对于多行字符串文字,最好使用三引号):
ee='''
Module-order DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
Order ::= SEQUENCE {
header Order-header
}
Order-header ::= SEQUENCE {
reference NumericString (SIZE (12)),
date NumericString (SIZE (8)) -- MMDDYYYY --
}END
seq_list=['Order','Order-header']
condition='Order ::= SEQUENCE {
header Order-header
}'''
rec_fn(ee, 'Order')
将返回:
{'header': {'reference': 'NumericString', 'date': 'NumericString'}}